UISearchBar with Controller in a normal UIView? - iphone

What I want:
A UIView with a UISearchBar at the top. Starting to edit the searchBar dims the current view and shows search results from another [UITableView]Controller.
What I've tried:
In Interface Builder:
add a "Search Bar and Search Display Controller" to the UIView.
add a placeholder object for my UITableViewController
add a UITableView object and set it as the view for the UITableViewController
set the delegate for the UISearchBar to the UITableViewController
set all the outlets on the UISearchDisplayController to the UITableViewController
In Code:
add the UISearchBarDelegate, UISearchDisplayDelegate protocols to the UITableViewController
What I'm getting:
Tapping to edit the search field crashes the app. No error messages, and only the "viewDidLoad" method in the UITableViewController gets called.
In Conclusion:
How do I go about using an external controller for a UISearchBar that is in a UIView?

Ok, so I've figured it out. I swear this is one of the first things I tried, but obviously I didn't do it correctly.
In my UIViewController (the one that has the UISearchBar in it), I instantiate a UISearchDisplayController:
// sb = IBOutlet UISearchBar
sc = [[SearchController alloc] initWithStyle:UITableViewStylePlain];
sdc = [[UISearchDisplayController alloc] initWithSearchBar:sb contentsController:sc];
sb.delegate = sc;
sdc.delegate = sc;
sdc.searchResultsDelegate = sc;
sdc.searchResultsDataSource:sc = sc; `
Where SearchController is my subclass of UITableViewController and adapts the UISearchBarDelegate and UISearchDisplayDelegate protocols.
Now that I think about it, using one linked from IB would probably work just as well (and in the same way)...
So the above works for me, but now the results tableView doesn't show up unless I manually add it to the main view: [self.view addSubview:sc.tableView]; but that's fodder for another question, I suppose.
There isn't any documentation on the web (as far as my google-fu is concerned) of a non-self-delegated UISearchDisplayController, so hopefully this helps out another Obj-C noob someday.

For one thing, if your Controller class is extending from UITableViewController, you can't have a search bar in it if you're using Interface Builder. Instead, extend from UIViewController and conform to the Table Data Source and Delegate protocols on your own.
But yeah, for that answer to be a good one for you, you're going to have to add some code or something to your question.

Related

Cannot add Outlet connection from Button to ViewController

I am trying to create an IBOutlet connection/reference from my button to my UIViewController in Xcode, but it is only giving me the "option" to add an Action connection. I am trying to utilize the viewDidLoad and baselineAdjustment to vertically center the buttons label when the text scales to fit the width, but am not having any luck.
Does anyone have a suggestion or know what I'm doing wrong?
EDIT: Adding a few more screenshots for clarity
If I select my main Scene View, the class is of type ViewController. If I select the view that the Button in question is a part of(it is in a ContainerView), it is of class UIViewController and the options do not present a choice of ViewController.
Make sure the right class subclassing the UIViewController, make sure when you are doing it, you choosing the UIViewController and not the View or the safe area.
Let me know if it solved it
I see the you have multiple ViewControllers in storyboard. Ideally, each View controller in the storyboard is supposed to be of only one type of UIViewController implementation and it's also true the other way around. so, If you have say 3 UIViewControllers in Your storyBoard, then you will need to create 3 .swift files which implement UIViewController like so:
abcVC:UIViewController { .....
efgVC:UIViewController { .....
ViewController:UIViewController { ..... //this is the default one you get.
and then set the class of each ViewController in your storyboard to one of each of the above.
if your ViewController which has the button you want to outlet has a class type abcVC, then you can outlet your button only in abcVc's implementation in abcVC.swift.
Hope it makes sense. to see how to set class, refer #Vadim F. 's answer.
and if you happen to upvote this answer, please also consider upvoting #Vadim F. 's answer.
This is how you can crate a new .swift file while subclassing a UIViewController: File -> new -> File -> Cocoa touch class -> #make it subclass of UIViewController and give it a unique name eg: abcVC
Certify that your ViewController in the Storyboard is of the class ViewController (i.e your view controller) and not from UIViewController.

How to get access to UITableViewController properties when subclassing from UIViewController?

I have subclassed UIViewController to provide common functionality for all UIViewControllers (for example I'm overriding viewDidLoad method). My app uses a bunch of view controllers that are arranged inside tab bar controller and in navigation controllers. Everything is OK, except the fact I have one UITableViewController. I would like to subclass not it but my custom MyUIViewController. I'm able to get the table working by implementing data source and delegate protocols:
#interface MaschinenTableViewController : MyUIViewController <UITableViewDataSource, UITableViewDelegate>
However in this case, I do not have an access to UITableViewController properties. For example, I cannot change the behavior of table row selection because self is MyUIViewController not UITableViewController:
self.clearsSelectionOnViewWillAppear = YES;
Are there any workarounds for accessing those properties?
In this case you will need to add a UITableView variable to the header and set it up appropriately in viewDidLoad, and add it to your view. From this point it will work as a UITableViewController will (as essentially that's all it does!)
Take a look at my article here which takes this approach.
You could also subclass UITableViewController as MyUITableViewController, implementing the behavior you want, and then put a MyUITableViewController as variable to your MyUIViewController.
Did the same as Simon Lee mentioned using the delegate.
But without storing the index anywhere, at the end of didSelectRowAtIndexPath method called the deselectRowAtIndexPath. Worked for me no issues so far.

UITableView with fixed image background

Sorry but I found no clear answer on that.
I have an iphone app with a tab bar and a UINavigationController in each tab.
The interface is built with Interface Builder, and in the first tab there is a UITableView.
I have prepared the xib with main view (A) containing a table (T) and an image (IMG) background behind (image as subview of main view).
Later I assigned UITableViewController as owner. This is where problems start.
In IB if I connect view to A I got a runtime error telling me that controller cannot find a table.
If I connect controller view to T everything works fine, except that IMG is not shown.
The only solution I found is to create a new xib holding A and IMG with a UIViewController as owner. Then create a xib holding T only and UITableViewController as owner, correctly connected to T.
Then in viewDidLoad of the UIViewController:
iptc = [[IPPlantsTableViewController alloc] initWithNibName:#"IPPlantsView" bundle:[NSBundle mainBundle]];
iptc.navigator=self.navigationController; // <-- need this
[self.view addSubview:iptc.view];
And this works, except that the table view seems to not know anything about navigationController, therefore detail view mechanism is not working, unless I set a property for it in UITableViewController.
I also run in to some other problems, for example all the logic for adding/deleting/creating rows to table has to be handled in UIViewController and sent to UITableViewController.
Is there another way for having a fixed image in a table view ?
Mmmm
I will be honest i HATE Interface Builder ;-) so I can't help you about this.
But to set a fixed image in the background of a UITableView you should :
- set background color of the UITableView to [ UIColor clearColor ] (and maybe the background of the cell too)
- set and uiimageview below the uitableview view that contains the image :)
In that way this should work.
But without xcode project I can't help you more ^^
Good luck
UITableViewController is a convenience class; you can equally just use UIViewController and implement the correct callbacks.
In OS 3.2+, you can just set UITableView.backgroundView. If IB doesn't let you do this, you can do it in code instead.
Alternatively, you might be able to wire up the view and tableView outlets differently, unless tableView just does (UITableView*)self.view.

Add views to "more" tab item

Is it possible to change appearence of "more" item in TabBarController? For example can I add custom views and change layout of tableView containing "more" controllers list?
Just find it was already discussed in
Customizing the More menu on a Tab bar
https://discussions.apple.com/thread/2399024
So we can get instance of this "More" ViewController using:
UIViewController *moreViewController = tabBarController.moreNavigationController.topViewController;
In fact it is of undocumented class UIMoreListController declared as:
#interface UIMoreListController : UIViewController <UITableViewDelegate, UITableViewDataSource>
moreViewController.view property contain UITableView and we can use it, for example add tableHeaderView:
UITableView *moreTableView = (UITableView*)moreViewController.view;
moreTableView.tableHeaderView = myOwnCustomView;
But I am not sure is this code "applesafe"? Because it use private class although not explicitly.
And what if I want to add a view that shouldn't scroll with table? Any ideas?
yes, this is all possible, if you could give us an example of what you want, maybe with a screenshot or something, then we can help you with some code examples
You can do what you want to do...
by using UITableViewController as a moreview tabbaritem.
and can create a moreview some what similar to the standard moreView controller.

Does UITableViewController allow the table to be in a UIView?

UITableViewController seems to always hijack the View link in IB. So, if I put UITableView in a UIView and link up the View to that UIView, it still doesn't work. Only the UITableView is shown.
What I'd like to do is use a UITableViewController and put some labels on top of the uiTableView that can be hidden.. Like loading.. and No results found.
The only solution I have come up with is to resort to using UIViewController and then adding a UITableView link to the class and link it up in IB.
Am I missing something here?
It's fine to use a UIViewController, make it implement the table view datasource and delegate protocols, and then hook a UITableView up to it. It's also fine to have the controller's main view be a container UIView, and have a UITableView as a subview of that.
And yes, this is probably the best way to add some kind of overlay view, such as a message label. So I think you're on the right track.
You should also be able to do this using a UITableViewController, instead of a UIViewController that explicitly implements the table view protocols. I've had success with this. I'm not sure what you mean when you say that UITableViewController "hijacks" the view outlet in IB.
It really isn't a big deal either way. UITableViewController doesn't do much other than implement those protocols, provide a different default loadView method, and call [tableView reloadData] by default on viewWillAppear:. If you do those things yourself, you'll be fine.