updateSearchResults() not getting called - search

I have read similar problems and solutions on SO. But none seems to solve my problem. I am using Custom Search Controller and Custom Search Bar and func updateSearchResults(for searchController: UISearchController) is not getting called.
var customSearchController: CustomSearchViewController!
CustomSearchViewController: In ViewDidLoad()
customSearchController = CustomSearchViewController(searchResultsController: ***nil***, searchBarFrame: CGRect(x: 0.0, y: 0.0, width: searchTableView.frame.size.width, height: 44.0), searchBarFont: UIFont(name: "HelveticaNeue", size: 16.0)!, searchBarTextColor: UIColor.purple, searchBarTintColor: UIColor.white)
customSearchController.searchResultsUpdater = self
customSearchController.definesPresentationContext = true
customSearchController.customSearchBar.placeholder = "What are you looking for?"
customSearchController.customSearchBar.backgroundColor = UIColor.white
customSearchController.customSearchBar.sizeToFit()
customSearchController.customSearchBar.resignFirstResponder()
customSearchController.customSearchBar.showsCancelButton = true
customSearchController.customSearchBar.delegate = self
Not getting called: :(
func updateSearchResults(for searchController: UISearchController) {
filtered.removeAll()
filtered = searchArray.filter({ (text) -> Bool in
let tmp: NSString = text as NSString
let range = tmp.range(of: customSearchController.customSearchBar.text!, options: NSString.CompareOptions.caseInsensitive)
return range.location != NSNotFound
})
self.searchTableView.reloadData()
}

After struggling for hours, I was able to solve it by using:
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) - UISearchBarDelegate delegate method.
instead of updateSearchResults() - UISearchResultsUpdating delegate method
Hope it helps someone :)

I had to declare UISearchController instance within the class scope. See this answer. https://stackoverflow.com/a/46781890/1511978
Previously I had declared it within the viewDidLoad method

It looks like you did not set this:
searchController.searchResultsUpdater = self
Make sure this is the last command to avoid getting errors. At least this did the job for me.

But maybe your problem was that you call that:
navigationItem.titleView = searchController.searchBar
Instead, you should do that:
navigationItem.searchController = searchController

Related

disable/hide UISearchBar when datasource is nil

I want to make sure that no search bar is displayed when the datasource of my table view is empty. (Makes sense, no? shouldn't that be default behaviour?)
Here's a piece of my code that tries (currently uncommented) different things to accomplish that, but somehow it doesn't work.
Can anybody advise me what I'm doing wrong? Let me know if you need more snippets.
messagesArray=loadMessages()
DispatchQueue.main.async {
if (self.messagesArray.count==0){
self.noMessageview.isHidden=false
//self.searchController.searchBar.isHidden = true
//self.searchController.isActive = false
} else{
self.noMessageview.isHidden=true
//self.searchController.searchBar.isHidden = false
//self.searchController.isActive = true
}
self.spinner.stopAnimating()
self.refreshControl.endRefreshing()
self.tableView.reloadData()
}
UPDATE:
I declare the search controller like this:
let searchController = UISearchController(searchResultsController: nil)
and in the ViewDidLoad I do:
navigationItem.searchController = searchController
I believe you are using iOS 11 because of setting UISearchController from navigationItem, Thus you can use the following code to remove it:
if #available(iOS 11.0, *) {
self.navigationItem.largeTitleDisplayMode = .never;
self.navigationItem.searchController = nil
} else {
// Fallback on earlier versions
self.navigationItem.titleView = nil
};
I had some problem and i think its iOS 11 bug, when removing the UISearchController, the view doesn't get adjusted thus i had to call this right before removing UISearchController.
self.navigationItem.largeTitleDisplayMode = .never;
Thats all.

Haxe for loop only uses last item

After some hours doing some testing I figured out that my map contains the correct values, but the loop that I am using only seems to be using the last added value in this map. Am I missing something obvious here?
The function that adds items to the map: (controls is the map variable)
public static function CreateThumbstick(mActorType:ActorType, mLocation:Int, mDirectionLock:Int)
{
var controllerName = "Thumbstick"+mLocation;
if(!controls.exists(controllerName)){
createRecycledActor(mActorType, 0, 0, Script.FRONT);
var lastActor = getLastCreatedActor();
var myPosition = GetPosition(controllerName, lastActor);
lastActor.setX(myPosition.x);
lastActor.setY(myPosition.y);
var myPos = new Vector2(lastActor.getXCenter(), lastActor.getYCenter());
var controlUnit = new ControlUnit(lastActor, myPos, -1);
controls.set(controllerName, controlUnit);
trace("added key: " + controllerName +" with value: "+ lastActor);
} else {
trace("!!WARNING!! Control unit already exists in this position. Command ignored!");
}
}
Upon creating 3 thumbsticks, the log states the following:
added key: Thumbstick1 with value: [Actor 1,Thumbstick]
added key: Thumbstick2 with value: [Actor 2,Thumbstick]
added key: Thumbstick3 with value: [Actor 3,Thumbstick]
When the screen is touched, it should loop through each item in my map, but it is using the last added item 3 times to check the distance with, rather then all 3 items once. Here is the Listener that is being called when the screen is touched:
addMultiTouchStartListener(function(event:TouchEvent, list:Array<Dynamic>):Void
{
for (unit in controls){
trace(lastDebugLine + "checking distance to " + unit.GetActor());
if(GetDistance(unit.GetCenter(), touch.GetPosition()) < 64){
break;
}
}
});
// used "touch.GetPosition()" instead of actuall code for easy reading. This is not causing any problems!
Upon touching the screen, the log states the following:
checking distance to [Actor 3,Thumbstick]
checking distance to [Actor 3,Thumbstick]
checking distance to [Actor 3,Thumbstick]
I am quite new to the Haxe language, so my guess is that I am missing something obvious, even after I have followed the Haxe API very closely. This is the example used from the Haxe API page:
var map4 = ["M"=>"Monday", "T"=>"Tuesday"];
for (value in map4) {
trace(value); // Monday \n Tuesday
}
All explanations are welcome!
Added ControlUnit class:
import com.stencyl.models.Actor;
class ControlUnit
{
static var actor;
static var center;
static var touchID;
public function new(mActor:Actor, mPosition:Vector2, mTouchID:Int)
{
actor = mActor;
center = mPosition;
touchID = mTouchID;
}
public function GetActor():Actor{
return(actor);
}
public function GetCenter():Vector2{
return(center);
}
public function GetTouchID():Int{
return(touchID);
}
}
You just used static for vars in class definitions - they aren't instance aware/based.
Check 'properties', getters, setters etc. in https://haxe.org/manual/class-field-property.html
Are you sure that getLastCreatedActor() is returning a separate instance each time? If it's returning the same instance each time you will likely see what you're getting.
Isn't that because all of your keys map to the same value? Try mapping them to different values and test it.

Fetch Request Result, Core Data & Swift 3

Now that NSFetchResultsController and NSFetchRequest are Generics in Swift 3, there have been a few changes in the initialization. I used the migrator (which was great!) and everything compiles fine. But the app crashes when I try and retrieve attributes the Swift 2 way.
I have thoroughly researched this problem.
There are few examples of how to initialize NSFetchResultsController and NSFetchRequest, but the various responses on StackOverflow are competing or currently inadequate when explaining the retrieval. Apple's documentation, too, is clear but not working.
Here is my code where Person is the Entity:
// MARK: - Initialize Fetch Results
var fetchedResultsController = NSFetchedResultsController<Person>()
func setFetchRequest() -> NSFetchRequest<Person> {
do {
let fetchRequest: NSFetchRequest<NSFetchRequestResult> = Giver.fetchRequest()
let fetchResult = try moc?.fetch(fetchRequest)
// CANNOT FIGURE OUT WHAT GOES HERE e.g.
// person.name = fetchResult.first (this does not work)
// person.name = fetchResults (this does not work)
let sortDescriptor = SortDescriptor(key: "names", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor]
} catch {
print("Error with request: \(error)")
}
return setFetchRequest()
}
// MARK: - Retrieve Fetch Request
func getFetchRequest() -> NSFetchedResultsController<Giver> {
fetchedResultsController = NSFetchedResultsController(fetchRequest: setFetchRequest(), managedObjectContext: moc!, sectionNameKeyPath: nil, cacheName: nil)
return fetchedResultsController
}
At the moment, there is no error, save the yellow triangle indicating that "fetchResult" has not been used. I am trying to fetch a few attributes: name: String, age: Int, photo: BinaryData. How would I retrieve these attributes?
I realize Swift 3 is still in beta. Just frustrated experiencing the pangs of source-breaking changes.

how to pass parameters to the closure if use #DelegatesTo annotation?

if i change the code in Groovy DSL Doc here.
add some string 'hello world' to email, like this
email('hello world') { // change here
from 'dsl-guru#mycompany.com'
to 'john.doe#waitaminute.com'
subject 'The pope has resigned!'
body {
p 'Really, the pope has resigned!'
}
}
and change
def email(def name, #DelegatesTo(EmailSpec) Closure cl) { // change here
def email = new EmailSpec()
def code = cl.rehydrate(email, this, this)
code.resolveStrategy = Closure.DELEGATE_ONLY
code.call(name) // change here
}
so, how to modify the class EmailSpec to get the string 'hello world' ??
To tell the compile that the closure will be called with a parameter you need to add the ClosureParams annotation.
To stick with your example:
def email(def name,
#ClosureParams(value = SimpleType, options = "java.lang.String")
#DelegatesTo(EmailSpec) Closure cl) {
def email = new EmailSpec()
def code = cl.rehydrate(email, this, this)
code.resolveStrategy = Closure.DELEGATE_ONLY
code.call(name) // change here
}
will tell the compiler that the first parameter is a String.
For more details have a look at the section The #ClosureParams annotation in the groovy documentation.
Yes, i found a way, but not perfect.
Simple
new EmailSpec(name) // change to
however, i really want to use groovy function call(name) to solve it

XCode 6 Beta 6 Error in Beta 7 - Value of optional type not unwrapped

I've been trying to do a simple CoreData task, saving data. I'm sure it works in Beta 6, but errors starting appearing after updating to Beta 7.
I think I have to add '?' or '!' based on the error hint, but just not smart enough to figure out where!
#IBAction func saveItem(sender: AnyObject) {
// Reference to App Delegate
let appDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
// Reference our moc (managed object content)
let contxt: NSManagedObjectContext = appDel.managedObjectContext!
let ent = NSEntityDescription.entityForName("List", inManagedObjectContext: contxt)
// Create instance of our data model and initialize
var newItem = Model(entity: ent, insertIntoManagedObjectContext: contxt)
// Map our attributes
newItem.item = textFieldItem.text
newItem.quanitity = textFieldQuantity.text
newItem.info = textFieldInfo.text
// Save context
contxt.save(nil)
}
The error says
Value of optional type 'NSEntityDescription?' not unwrapped; did you mean to use '!' or '?'
At the line
var newItem = Model(entity: ent, insertIntoManagedObjectContext: contxt)
Everytime I seem to have clear the error and compiles ok, clicking the 'Save' shows in the debug area
fatal error: unexpectedly found nil while unwrapping an Optional value
The error is fairly trivial, there's not much to analyze here. Try changing this:
let ent = NSEntityDescription.entityForName("List", inManagedObjectContext: context)
to this
let ent = NSEntityDescription.entityForName("List", inManagedObjectContext: context)!
As always, novices tend to overlook tell-tale signs. The error clearly states that the optional is of type NSEntityDescription. And given that there is only object of this type being instantiated in the given code, it doesn't take a genius to guess where the error lies.
Value of optional type 'NSEntityDescription?' not unwrapped; did you mean to use '!' or '?'
Also, method used here to instantiate the NSEntityDescription object is declared as follows:
class func entityForName(entityName: String, inManagedObjectContext context: NSManagedObjectContext) -> NSEntityDescription?
... the ? character clearly telling us that this method returns an optional.
I presume that the Model initializer signature is:
init(entity: NSEntityDescription, insertIntoManagedObjectContext: NSManagedObjectContext)
the compilation error happens because NSEntityDescription.entityForName returns an optional, so you have to unwrap it.
As for the runtime error, my guess is that contxt is nil, and you are passing a forced unwrapped here:
let ent = NSEntityDescription.entityForName("List", inManagedObjectContext: contxt)
To made code safer and more clear, I'd explicitly use optionals:
let contxt: NSManagedObjectContext? = appDel.managedObjectContext
if let contxt = contxt {
let ent: NSEntityDescription? = NSEntityDescription.entityForName("List", inManagedObjectContext: contxt)
// Create instance of our data model and initialize
if let ent = ent {
var newItem = Model(entity: ent, insertIntoManagedObjectContext: contxt)
}
}
and use debugger & breakpoints to check if any of the mentioned variable is nil.

Resources