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.
Related
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.
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 viewcontroller which contains an instance variable containing a dictionary object with a bunch of data. The view is fairly complex and contains several subviews that i instantiate and embed from seperate view files(To avoid having a thousand lines of UI code in the actual viewcontroller) - But how do these subviews, which exists in their own files, get access to my dictionary object from the viewcontroller?
So when im editing the DescriptionView.m file - How do i get access to the contents of the locationData dictionary object from the ViewController?
Hope you understand what i mean.
Here's a snippet from the ViewController:
CaseViewController.h
#import "DescriptionView.h"
#interface CaseViewController : UIViewController {
NSDictionary *locationData;
DescriptionView *descriptionView;
}
#property (nonatomic, retain) NSDictionary *locationData;
#property (nonatomic, retain) DescriptionView *descriptionView;
#end
CaseViewController.m
- (void)loadView {
UIView *view = [[UIView alloc] init];
descriptionView = [[DescriptionView alloc] initWithFrame:CGRectMake(0, 130, 320, 237)];
descriptionView.hidden = NO;
[view addSubview:descriptionView];
self.view = view;
[view release];
}
Ideally you should never access any properties of viewcontroller from the view.
The main idea of MVC architecture is that viewcontroller tells it's views what to render and not vise versa.
So you just have to provide all the data that your view needs for rendering during it's initialization:
- (void)loadView {
UIView *view = [[UIView alloc] init];
descriptionView = [[DescriptionView alloc] initWithFrame:CGRectMake(0, 130, 320, 237) paramDict: self.locationData]; descriptionView.hidden = NO;
[view addSubview:descriptionView];
[descriptionView release]; // BTW add this line here (or in dealloc) or you'll have a leak
self.view = view; [view release];
}
If you need to update your view dynamically, then you should add some methods to your view and call them from viewcolnroller.
E.g.:
DescriptionView.m:
-(void) updateWithDict:(NSDictionary*) udict;
If you need to perform some actions when some button in DescriptionView is pressed (or any other user interaction) a good idea would be declaring a protocol like DescriptionViewDelegate (or smth like that):
-(void) descriptionViewButton1Pressed:(DescriptionView*) dview;
-(void) descriptionViewButton2Pressed:(DescriptionView*) dview;
then make your CaseViewController a delegate and implement that methods there.
The simpliest way to have a reference to its viewcontroller from a view is to extend UIView:
#interface MyView: UIView {
UIViewController *mViewController;
}
Then in loadView
MyView *view = [[MyView alloc] init];
view.mViewController = self;
removeFromSuperview not working Properly?
I added one button over another button.
When i try to remove the latter button from the view using removeFromSuperview function call , it does not worked.
the following Code works for me perfectly;
header file
#interface ViewController : UIViewController
{
UIButton *btnShadow;
}
#property (nonatomic,retain) UIButton *btnShadow;
implementation
#synthesize btnShadow;
-(void) vDrawGrayView
{
btnShadow = [[UIButton alloc] initWithFrame:CGRectMake(0, 44, 320, 416)];
btnShadow.backgroundColor = [UIColor colorWithRed:((CGFloat)79/255) green:((CGFloat)73/255) blue:((CGFloat)73/255) alpha:1];
[btnShadow addTarget:self action:#selector(HideKeyboard) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btnShadow];
}
whenever you need to remove the button use:
[btnShadow removeFromSuperview];
note
Dont fotget to release the button and make sure you are removing the button that is on the front, you can make it in the front of the UIView by using:
[self.view bringSubviewToFront:btnShadow];
Good luck.
I want to add a UISlider to my app programmatically without using the IB.
I am adding a UISlider to my UIViewController using the code below. However I don't see the slider when the view comes up. What am I missing? I am using iPhone SDK 3.1.2.
Appreciate any help.
#synthesize slider;
....
- (void)viewDidLoad {
...
...
slider = [[UISlider alloc] initWithFrame: CGRectMake(0, 480 - 80, 300, 20)];
slider.minimumValue = 0.0;
slider.maximumValue = 100.0;
slider.tag = 0;
slider.value = 50;
slider.continuous = YES;
slider.enabled = YES;
[slider addTarget:selfaction:#selector(handleSlider:)forControlEvents:UIControlEventValueChanged];
self.view addSubview:slider];
In the .h file
...
UISlider *slider;
...
#property (nonatomic, retain) UISlider *slider;
- (void) handleSlider:(id)sender;
Possibilities:
If the slider isn't the last view added, its likely its being hidden by another view.
The self.view is actually smaller than {0,400}.
The sliders hidden attribute is set to true.
You have more than one view controller active at a time.
You should check the debugger for the self.view's subviews and see if the slider is there. If so then it's almost certainly one of the reasons above.