I've been trying to find the solution for hours, but alas no dice...
I've been trying to implement a UISearchBar purely programatically (no xib, no interface builder).
Here is my .h header:
#interface RLCASearchMasterViewController : UIViewController<UISearchBarDelegate>
#property (strong, nonatomic) RLCAGUIElements *gui;
#property (strong, nonatomic) RLCAUITableView *table;
#property (strong, nonatomic) UISearchBar *searchBar;
#end
and my .m implementation:
#synthesize searchBar;
- (void)loadView
{
[super loadView];
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, searchBar.frame.size.height)];
searchBar.delegate = self;
[self.view addSubview:searchBar];
}
I'd gone over this I don't know how many times, and have no idea what I'm doing wrong...
The UISearchBar is added to the view just fine, with the correct size and all, however when clicked/tapped, the keyboard does not come up.
If I evoke the following however:
[searchBar becomeFirstResponder];
the keyboard does show, so it's probably not the delegation but actually detecting whether it's been clicked... I do not want it to edit on load though, and only by request...
Please help. Thanks! :)
Sincerely,
Piotr.
Okay, I got it to work.
It works but I have no idea why. If someone has any insight, I would be very grateful...
So:
I replaced:
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, searchBar.frame.size.height)];
searchBar.delegate = self;
[self.view addSubview:searchBar];
with:
searchBar = [[UISearchBar alloc] init];
searchBar.delegate = self;
[searchBar sizeToFit];
[self.view addSubview:searchBar];
...aaand, VIOLA! ;)
Thanks for all the answers though, and as mentioned, would appreciate an explanation why this worked and what it did.
All the best,
Piotr.
searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.frame.size.width, searchBar.frame.size.
You shouldn't access the searchBars frame for use in its own init method. I would think, since at that moment it has NOT yet been inited, it will be 0 thus giving you a rect with no height, or maybe an NSZeroRect because the makeRect failed completely
I think that's the problem.
Try defining its delegate methods and put the becomes first responder method in the searchBarShouldBeginEditing method. If it is still not working, make sure if there is not any other view on top of this view. In this way, it will be overriding the touch.
Related
When my UITextView is being edited, I want a button to appear. How can I do this?
Thanks!
Implemetn UITextViewDelegate in your class and when editing is being started on UITextView
it'll call it's textViewShouldBeginEditing: function where you can do whatever you want. You can show your button when editing start and hides when editing ends in this function.
– textViewShouldEndEditing
For further detail see this
i will detail above answer a little bit:
YourViewController.h
#interface YourViewController : UIViewController <UITextViewDelegate>
YourViewController.m
- (void)viewDidLoad
{
[super viewDidLoad];
self.yourTextView.delegate = self;
}
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView{
// do smth like create a button
return TRUE;
}
Read Apple manual for more
Check out the UITextViewDelegate Protocol Reference. If you set your UIViewController to be the delegate of the UITextView, it will be sent textViewDidBeginEditing: and textViewDidEndEditing:. You can show/hide your button when you receive those messages.
//in view did load.
UITextField entered1 = [[UITextField alloc] initWithFrame:CGRectMake(120.0, 85.0, 150.0, 25.0)];
[entered1 setBackgroundColor:[UIColor whiteColor]];
[entered1 addTarget:self action:#selector(example:)forControlEvents:UIControlEventTouchDown];
[self.view addSubview:entered1];
[entered1 release];
or
[textfieldname addTarget:self action:#selector(example:)forControlEvents:UIControlEventTouchDown];
.........
}
-(IBAction) example:(UIControl *)sender
{
//your code here.
}
Xcode 6.4, iOS 8.4, ARC Enabled
Don't make my mistake, took me a long time to figure it out, but I was adding...
#interface YourViewController : UIViewController <UITextFieldDelegate>
because I am used to working with UITextField's, but obviously we need...
#interface YourViewController : UIViewController <UITextViewDelegate>
Hope this saves someone time. Cheers!
I have a UIViewController that is a UISearchBarDelegate and a MKMapViewDelegate. The searchBarSearchButtonClicked event works fine, but when testing in iOS 4.2 the searchBarCancelButtonClicked never gets called when hitting the cancel button. In 4.3 everything works fine. I have other views with identical code and it works fine. I have triple checked the method signatures.
Could it be something to do with the MapView, or am I doing something blatantly wrong?
My .h file:
#interface MyViewController : UIViewController <UISearchBarDelegate,MKMapViewDelegate,UIAlertViewDelegate>{
MKMapView *mapMainView;
UISearchBar *sBar;
}
#property (nonatomic, retain) UISearchBar *sBar;
#end
And I create the search bar like so:
sBar = [[[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320.0, 70.0)] autorelease];
sBar.delegate = self;
sBar.showsCancelButton = YES;
[self.view addSubview:sBar];
[sBar becomeFirstResponder];
The method:
- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
[searchBar resignFirstResponder];
searchBar.hidden = YES;
}
Does anyone have an idea of why this may be happening?
I had the exact same problem. Holding the cancel button for a few seconds worked.
The reason for me was that I had implemented UITapGestureRecognizer in the tableview. So this took precedence over the button click or 'x' button click in the search bar.
The solution in my case was to restrict the gesture recognition to only the backgroundview of the tableview. I guess similar thing might be happening in your case. Try to restrict the gesture recognizers to the minimum subview required and the search bar should be outside that view.
Probably your sbar object are releasing, in this case is an autorelease object, Why ?. Try declaring sBar as IBOutlet property. Make the apropiate links in the Interface Builder, remove the alloc as you code it, put in viewDidUnload
self.sbar = nil;
and releas it in dealloc. in viewDidLoad put this.
sBar.delegate = self;
sBar.showsCancelButton = YES; // this is an option in object inspector
[self.view addSubview:sBar];
[sBar becomeFirstResponder]; //remove this.
Tell me if it works
try this:
sBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320.0, 70.0)];
sBar.delegate = self;
sBar.showsCancelButton = YES;
[self.view addSubview:sBar];
and try to put release in dealloc
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (tableView == self.searchDisplayController.searchResultsTableView)
{
[self.searchDisplayController setActive:NO animated:YES];
[self.searchDisplayController.searchBar resignFirstResponder];
}
}
I have a UIViewController which has a grouped UITableView as a property. I instantiate the UITableView in code and don't use IB. I would like to hook up a UISearchDisplayController to it but can't find any example how this could be done.
This what I have.
//Have implemented the UISearchDisplayDelegate in the header file
//SearchBar
UISearchBar *searchBar = [[UISearchBar alloc]initWithFrame:CGRectMake(0, 0, 320, 45)];
searchBar.barStyle=UIBarStyleBlackTranslucent;
searchBar.showsCancelButton=NO;
searchBar.autocorrectionType=UITextAutocorrectionTypeNo;
searchBar.autocapitalizationType=UITextAutocapitalizationTypeNone;
searchBar.delegate=self;
UISearchDisplayController *mySearchDisplayController = [[UISearchDisplayController alloc ]initWithSearchBar:searchBar contentsController:self];
self.searchDisplayController = mySearchDisplayController; //Error here ?? self.searchDisplayController is ReadOnly and can't assign
[self.searchDisplayController setDelegate:self];
[self.searchDisplayController setSearchResultsDataSource:self];
[mySearchDisplayController release];
[myDisplayController release];
This doesn't seem to work, the searchDisplayController propery of the UIViewController seems to be readonly and I can't hook myDisplayController onto it. I'm really not sure if this the right way to do it.
I've been looking all around google to find some tip or tutorial on how to use a UISearchDisplayController in UIViewController. All the examples I could find was how to implement it into UITableViewController using IB, which is not the way I want to use it.
Can anyone explain how I could get this working ?
Here's the code that I use. Put this in viewDidLoad of a UIViewController that instantiates it's own UITableView. I think the part you're looking for is to add the search bar as the header view of the table view.
UISearchBar * theSearchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0,0,320,40)]; // frame has no effect.
theSearchBar.delegate = self;
if ( !searchBarPlaceHolder ) {
searchBarPlaceHolder = #"What are you looking for?";
}
theSearchBar.placeholder = searchBarPlaceHolder;
theSearchBar.showsCancelButton = YES;
self.theTableView.tableHeaderView = theSearchBar;
UISearchDisplayController *searchCon = [[UISearchDisplayController alloc]
initWithSearchBar:theSearchBar
contentsController:self ];
self.searchController = searchCon;
[searchCon release];
searchController.delegate = self;
searchController.searchResultsDataSource = self;
searchController.searchResultsDelegate = self;
[searchController setActive:YES animated:YES];
[theSearchBar becomeFirstResponder];
See the Apple Docs:
#property(nonatomic, readonly, retain) UISearchDisplayController *searchDisplayController
Discussion: This property reflects the value of the
searchDisplayController outlet that you set in Interface Builder. If
you create your search display controller programmatically, this
property is set automatically by the search display controller when
it is initialized.
I'm trying to create a tableview with a searchbar inside the header view of the table. I'd like to use a searchDisplayController to manage everything.
I've created everything programmatically (I'm not feeling comfortable with IB) trying to set all the correct properties, but it seems that I'm missing something, because when the table shows up I'm not able to edit the text in the searchbar and see any animation.
Here is a part of the code:
- (void)viewDidLoad {
[super viewDidLoad];
UISearchBar *searchBarTMP=[[UISearchBar alloc]init];
self.searchBar=searchBarTMP;
[searchBarTMP release];
self.searchBar.autocapitalizationType=UITextAutocapitalizationTypeNone;
self.searchBar.delegate=self;
self.searchBar.showsScopeBar=YES;
self.searchBar.keyboardType=UIKeyboardTypeDefault;
self.searchBar.userInteractionEnabled=YES;
self.searchBar.multipleTouchEnabled=YES;
self.searchBar.scopeButtonTitles=[NSArray arrayWithObjects:NSLocalizedString(#"City",#"Scope City"),NSLocalizedString(#"Postal Code",#"Scope PostalCode"),nil];
self.tableView.tableHeaderView=searchBar;
self.searchBar.selectedScopeButtonIndex=0;
self.navigationItem.title=NSLocalizedString(#"Store",#"Table title");
//SearchDisplayController creation
UISearchDisplayController *searchDisplayControllerTMP = [[UISearchDisplayController alloc] initWithSearchBar:self.searchBar contentsController:self];
self.searchDisplayController=searchDisplayControllerTMP;
[searchDisplayControllerTMP release];
self.searchDisplayController.delegate=self;
self.searchDisplayController.searchResultsDelegate=self;
self.searchDisplayController.searchResultsDataSource=self;
//....continue
}
I know that when you use a searchbar alone you must deal with its delegate protocol, but I'm guessing that the searchDisplayController manage for you as seen in the Apple sample code. (build up with IB).
Any suggestion?
Thank you,
Andrea
Found it...
After putting in the header of the table view must write
[self.searchBar sizeToFit];
If you are using ARC, make sure you create an iVar for the UISearchDisplayController in your header file.
If you create an UISearchDisplayController using:
UISearchDisplayController* searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchField contentsController:self];
it will get released by ARC, it will not call any delegate methods and when you'll call self.searchDisplayController (the UIViewController's property) it will be nil.
So, the fix is:
In your header (.h) file:
#interface MenuViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate, UISearchDisplayDelegate> {
UISearchDisplayController* searchDisplayController;
UISearchBar *searchField;
UITableView* tableView;
NSArray* searchResults;
}
and in the implementation (.m) file:
searchField = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 49)];
searchField.delegate = self;
searchDisplayController = [[UISearchDisplayController alloc] initWithSearchBar:searchField contentsController:self];
searchDisplayController.delegate = self;
searchDisplayController.searchResultsDataSource = self;
searchDisplayController.searchResultsDelegate = self;
tableView.tableHeaderView = searchField;
tableView.contentOffset = CGPointMake(0, searchField.frame.size.height);
When implemented like that, you can call both self.searchDisplayController and searchDisplayController in the rest of your code.
I am running into a very annoying problem: I am creating an UIScrollView that containes an UIView that contains some buttons. The UIView with buttons work fine. But the UIScrollView, no matter what I do with it, when touched, crashes. It doesn't make any difference it's empty or not. It keeps crashing.
I am very lost and don't know what else to try.
Thanks very much.
In the viewController.h
#interface tagstestViewController : UIViewController <UIScrollViewDelegate> {
UIScrollView *scrollViewContainer;
}
#property (nonatomic, retain) UIScrollView *scrollViewContainer;
In the viewController.m:
UIScrollView *scv = [[UIScrollView alloc] initWithFrame:CGRectMake(0,0, 320, 200)];
scv.backgroundColor = [UIColor blackColor];
scv.autoresizingMask = UIViewAutoresizingFlexibleHeight;
scv.bounces = YES;
scv.scrollEnabled = YES;
scv.clipsToBounds = YES;
scv.delegate = self;
[self setScrollViewContainer:scv];
[scv release];
[self.view addSubview:scrollViewContainer];
Are you releasing your viewController right after you add its view into the view hierarachy? Because if you do that, I noticed that even though the application keeps running fine, if you use "scv.delegate = self", it will crash when it tries to deliver the delegated messages to the viewController.