UIScrollView Stop working after push view to UINavigationController - ios

The scrollview in my main page stop working if I push something to the navigation controller and then pop back to the main page. It works normally if I reopen the application without pushing anything to the navigation controller yet. The scrollview is a horizontal scrollview which extends beyond the frame. I use it to scroll through buttons like when you switch application in iOS (iOS multitasking).
This is the code where I push a new vc
UIViewController *newVC = [[UIViewController alloc] init];
UILabel *label = [[UILabel alloc] initWithFrame:self.view.bounds];
[label setTextAlignment:NSTextAlignmentCenter];
label.text = [NSString stringWithFormat:#"promo %i detail view",[sender tag]];
label.backgroundColor = [UIColor whiteColor];
[newVC.view addSubview:label];
[self.navigationController setNavigationBarHidden:NO animated:NO];
[self.navigationController pushViewController:newVC animated:YES];
when that view controller is popped and navigation controller move back to the main page I hide the navigationBar.
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if(viewController == self){
[self.navigationController setNavigationBarHidden:YES];
NSLog(#"%d", [self.scrollMenuBar isScrollEnabled]);
}
}
checking isScrollEnable return true.
I tried pushing a normal modal view and the same problem occur.

If you resize the scroll view content size in the viewDidLayoutSubview function it will work again.
- (void) viewDidLayoutSubviews {
[self resizeScrollViewContent];
}

Add
[self.scrollbarMenu setScrollEnabled:YES]; in viewdidAppear of main page
Add
[scroll setContentSize:CGSizeMake(width , height)];
Still if it doesnt work
2 possibilities
Memory is not valid.
Some other view comes above the scrollview

Problem solved by creating the UIScrollview and the button inside it programmatically. Not sure what I did wrong with storyboard, but it's a pain.

Related

View pushed down after status bar hides?

I have a UIViewController with no status bar, and it launches a second UIViewController that has a status bar.
If the extended status bar is active, both views show correctly, but when I exit the second view and go back to the first, I see a 20pt black bar at the top and the whole view is pushed down, obscuring the bottom.
I tried resetting the frame to origin 0,0 in viewDidAppear but it has no effect.
Why is the view pushed down and how can I fix it?
- (BOOL)prefersStatusBarHidden {
return YES;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.view.frame = CGRectMake(0, 0, self.width, self.height);
self.view.backgroundColor = [UIColor redColor];
}
- (void)openShare {
Share *share = [[Share alloc] init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:share];
nav.modalTransitionStyle = UIModalPresentationPopover;
[self presentViewController:nav animated:YES completion:nil];
}
top of the view before openShare is called:
top of the view after Share is presented and dismissed:
Yesterday I had the exact same problem in my app.
I made two things that solve the problem.
I set the Top Space to: Top Layout Guide constraint with a constant of 20 (same as status bar height) on my navigationBar
I added this in the controllers that have the issue ([self.view layoutSubviews])
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.view layoutSubviews];
}

Resizing behavior of UIPopoverController differs between iOS 7.0 and iOS 7.1

I have a UIPopoverController that contains a UITableViewController within a UINavigationController.
Whenever a cell in this table view is pressed, I push yet another UITableViewController to my navigation Controller.
I want to set the height of my second table view (let's say to 200) and adjust the size of the popover accordingly.
I therefore first set the table view frame in viewDidAppear:(BOOL)animated and then call setPopoverContentSize:(CGSize)size animated:(BOOL)animated. Both heights are set to 200.
The resizing works, but there are the following differences on the different iOS versions:
iOS 6.1
As intended: The resized popover has the height 200 + the height of the navigation bar.
iOS 7.0
Not as intended: The resized popover has the height 200, including the height of the navigation bar.
iOS 7.1
As intended: The resized popover has the height 200 + the height of the navigation bar.
The resizing is for some reason animated, the table view is shortly displayed behind the navigation bar.
I can live with the different heights as those can be adjusted depending on the iOS version. I don't like the ugly animation, though. Do you have any idea how I can achieve my goal without this glitch?
Here comes a screenshot of the effect I want to avoid:
Here's, how I create the UIPopoverController:
- (IBAction)showPopup:(id)sender
{
MyTableViewController *table = [[MyTableViewController alloc] initWithStyle:UITableViewStylePlain];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:table];
nav.navigationBar.tintColor = [UIColor orangeColor];
UIPopoverController *pop = [[UIPopoverController alloc] initWithContentViewController:nav];
table.parentPopover = pop;
UIView *origin = (UIView *)sender;
CGRect buttonRect = CGRectMake(origin.frame.origin.x, origin.frame.origin.y, origin.frame.size.width, origin.frame.size.height);
[pop presentPopoverFromRect:buttonRect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
}
When a table cell is pressed, I push another table view controller:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
MyNextTableViewController *next = [[MyNextTableViewController alloc] initWithStyle:UITableViewStylePlain];
next.parentPopover = self.parentPopover;
[self.navigationController pushViewController:next animated:YES];
}
And here's what I do to resize the 'final' table view and the popover:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.tableView.frame = CGRectMake(0, 0, self.tableView.frame.size.width, 200);
[self.parentPopover setPopoverContentSize:[self contentSizeForViewInPopover] animated:NO];
}
- (CGSize)contentSizeForViewInPopover
{
return CGSizeMake(320, self.tableView.frame.size.height);
}
Btw, I know that - (CGSize)contentSizeForViewInPopover is deprecated from iOS 7.0 on, but I want to support iOS 6 and the problem described above also occurs when using - (CGSize)preferredContentSize. Same problem with UIScrollView, not only UITableView.
EDIT:
I filed a bug report with Apple with bug number 16865330.
This is a bug in popover controller in iOS7 and above. Please open a bug report with Apple in https://bugreport.apple.com and post the bug number in your question.
This happens due to resizing the popover controller in viewDidAppear. The key is to delay the resizing just a little bit, so that the popover controller can finish its layout. Using dispatch_async on the main queue, you register your block to run on a followup pass of the main runloop, which gives the popover controller enough time to "breed" and the bug is not reproduced.
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.tableView.frame = CGRectMake(0, 0, self.tableView.frame.size.width, 200);
dispatch_async(dispatch_get_main_queue(), ^{
[self.parentPopover setPopoverContentSize:[self contentSizeForViewInPopover] animated:NO];
});
}

On iOS 7, pushing a controller with a toolbar leaves a gap of unusable space if it's ultimately contained within a tab bar controller

In my iOS app, my window's rootViewController is a tab bar controller with the a hierarchy like this:
UITabBarController
UINavigationController 1
FirstContentController
UINavigationController 2
...
UINavigationController 3
...
...
When the user taps a certain row on FirstContentController, an instance of SecondController will be pushed onto its navigation controller. SecondContentController sets hidesBottomBarWhenPushed to YES in its init method and sets self.navigationController.toolbarHidden to NO in viewWillAppear:.
In iOS 6, the user would tap the row in FirstController and SecondController would get pushed onto the nav controller. Because it has hidesBottomBarWhenPushed set, it would hide the tab bar and, by the time the transition animation was complete, SecondController would be on the screen with its toolbar visible.
However, when testing this under iOS 7, hidesBottomBarWhenPushed's behavior seems to have changed. What I see now is:
the tab bar hides, as expected
the toolbar appears, as expected
a gap of unusable space exactly 49 pixels tall (the height of the tab bar) appears between the toolbar and the content view
The gap is completely unusable - it doesn't respond to touches and if i set clipsToBounds to YES on the main view, nothing draws there. After a lot of debugging and examining subview hierarchies, it looks like iOS's autosizing mechanism resizes the view controller's view to a height of 411 (on the iPhone 5). It should be 460 to reach all the way down to the toolbar, but the layout system seems to be including a "ghost" 49-pixel-tall tab bar.
This problem only occurs if the view controller has a tab bar controller as one if its parent containers.
On iOS 7, how can I have the tab bar disappear and a toolbar seamlessly slide into place when a new controller is pushed, and still have the view take up the entire space between the navigation item and the toolbar?
UPDATE
After further investigation, this only happens if SecondController's edgesForExtendedLayout is set to UIRectEdgeNone. However, unless I set that property to UIRectEdgeNone, the view's frame is too long and extends under the toolbar, where it can't be seen or interacted with.
I found that adding the following 2 lines of code in viewDidLoad of SecondViewController (where you want to hide TabBar but show the tool bar) fixes the problem.
self.extendedLayoutIncludesOpaqueBars = YES;
self.edgesForExtendedLayout = UIRectEdgeBottom;
My viewDidLoad of SecondViewController is as follows:
- (void)viewDidLoad {
[super viewDidLoad];
// These 2 lines made the difference
self.extendedLayoutIncludesOpaqueBars = YES;
self.edgesForExtendedLayout = UIRectEdgeBottom;
// The usual configuration
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
self.navigationController.navigationBar.translucent = NO;
self.navigationController.toolbarHidden = NO;
self.navigationController.toolbar.barStyle = UIBarStyleBlack;
self.navigationController.toolbar.translucent = NO;
.
.
}
But you need to fix the frame of the view manually as this causes the size to be (320x504). Which means it extends even behind the tool bar. If this is not a concern for you then this solution should work.
You will not like this answer This is not the answer you want, but after some research on hiding the tab bar in iOS7, my conclusion is: don't!
Tab bars have never been meant to be hidden - after all why have a UITabBarController if you want to hide the tab bar. The hidesBottomBarWhenPushed on view controllers is for hiding the bottom bar of a navigation controller, not tab bars. From the documentation:
A view controller added as a child of a navigation controller can display an optional toolbar at the bottom of the screen. The value of this property on the topmost view controller determines whether the toolbar is visible. If the value of this property is YES, the toolbar is hidden. If the value of this property is NO, the bar is visible.
Moreover, you are warned not to modify the tab bar object directly. Again, from the documentation:
You should never attempt to manipulate the UITabBar object itself stored in this property.
This is exactly what you are doing when setting it to hidden.
In iOS6 this has worked, but now in iOS7, it doesn't. And it seems very error prone to hide it. When you finally manage to hide it, if the app goes to the background and returns, Apple's layout logic overrides your changes.
My suggestion is to display your data modally. In iOS7 you can create custom transitions, so if it is important to you to have a push transition, you can recreate it yourself, although this is a bit over the top. Normal modal transition is something users are familiar, and actually fits this case better than push which hides the tab bar.
Another solution is to use a toolbar instead of a tab bar. If you use the navigation controller's toolbar for your tabs, you can then use hidesBottomBarWhenPushed as you require and it would give you the behavior you expect.
Uncheck "Hide bottoms bars on push" and set your autoconstraints as if there is a tab bar. Then in "ViewDidLoad" of the controller you want to hide the system tab bar, put the following code.
[self.tabBarController.tabBar setFrame:CGRectZero];
This makes sure the tab bar still accepts user interaction yet not visible to users. (other alternatives such as setting it 0 alpha or hidden will render tab bar useless) Now the autoconstaraints will make sure your view displays correctly with the tab bar height as zero.
It's a bug in iOS 7 UIKit due to this particular combination of:
UITabBarController
hidesBottomBarWhenPushed = YES
edgesForExtendedLayout = UIRectEdgeNone
UINavigationController toolbar
You should file a bug with Apple and include your sample code.
To work around the bug you need to remove one of those four conditions. Two likely options:
Fix the layout of your "second" view controller so that it works correctly when edgesForExtendedLayout is set to UIRectEdgeAll. This could be as simple as setting the contentInset on a scroll view.
Don't use UINavigationController's built-in toolbar. Instead, create a separate UIToolBar instance and manually add it to your second view controller's view.
You do have to set the tabBar of the TabBarController to hidden and your view should have autosizing set to flexible height.
With this code it's working:
#implementation SecondController
-(id)init
{
if( (self = [super init]) )
{
}
return self;
}
- (void)viewDidLoad;
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor redColor];
self.view.autoresizingMask = UIViewAutoresizingFlexibleHeight;
self.tabBarController.tabBar.hidden = YES;
}
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// will log a height of 411, instead of the desired 460
NSLog(#"frame: %#", NSStringFromCGRect(self.view.frame));
}
#end
Or, if you do want to use the hidesBottomBarWhenPushed method, you have to do this before you push the view controller obviously:
-(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath
{
SecondController* controller = [[SecondController alloc] init];
controller.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:controller animated:YES];
}
If using the second method, your viewDidLoad method can get rid of flexible height method as well as tabBarHidden:
- (void)viewDidLoad;
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor redColor];
self.edgesForExtendedLayout = UIRectEdgeNone;
}
See the result:
The key to this conundrum is that the navigationcontroller.view.frame size doesn't change. Going of batkin's Gist here is a gist of my own.
FirstViewController.m
#import "FirstController.h"
#import "SecondController.h"
#implementation FirstController
-(id)init
{
if( (self = [super init]) )
{
self.tabBarItem.title = #"Foo";
self.tabBarItem.image = [UIImage imageNamed:#"Tab Icon.png"];
}
return self;
}
-(NSInteger)tableView:(UITableView*)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
UITableViewCell* cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
cell.textLabel.text = #"Click";
return cell;
}
-(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath
{
SecondController* controller = [[SecondController alloc] init];
self.tabBarController.tabBar.hidden = YES;
[self.navigationController pushViewController:controller animated:YES];
}
#end
SecondViewController.m
#import "SecondController.h"
#implementation SecondController
-(void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.view.backgroundColor = [UIColor redColor];
self.view.clipsToBounds = YES;
/* ENTER VORTEX OF DESPAIR */
// without this, there's no gap, but the view continues under the tool
// bar; with it, I get the 49-pixel gap thats making my life miserable
self.edgesForExtendedLayout = UIRectEdgeNone;
//this resizes the navigation controller to fill the void left by the tab bar.
CGRect newFrame = self.navigationController.view.frame;
newFrame.size.height = newFrame.size.height + 49;
self.navigationController.view.frame = newFrame;
/* EXIT VORTEX OF DESPAIR */
self.navigationController.toolbarItems = #[
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:nil action:nil]
];
}
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.navigationController.toolbarHidden = NO;
// will log a height of 411, instead of the desired 460
NSLog(#"frame: %#", NSStringFromCGRect(self.view.frame));
NSLog(#"frame: %#", NSStringFromCGRect(self.navigationController.view.frame));
}
-(void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
self.tabBarController.tabBar.hidden = NO;
self.navigationController.toolbarHidden = YES;
//this resizes the navigation controller back to normal.
CGRect newFrame = self.navigationController.view.frame;
newFrame.size.height = newFrame.size.height - 49;
self.navigationController.view.frame = newFrame;
//this is optional and resizes the view to fill the void left by the missing toolbar.
CGRect newViewFrame = self.view.frame;
newViewFrame.size.height = newViewFrame.size.height + 49;
self.view.frame = newViewFrame;
}
#end
If you are using Auto Layout,make sure you pin the view to its superview instead of Top Layout Guide or Bottom Layout Guide.
Have you tried to move your call hidesBottomBarWhenPushed in the viewDidLoad or before the secondViewController is pushed?
With ios7, a lot of timing issues appear if you don't do the calls at teh good moment.
You mention that you can fix this by not touching the edgesForExtendedLayout. Is there a necessary reason that the content/controls of the view controller are contained in the root view of the pushed view controller? You might consider wrapping everything in a view that is the first and only child of the main view. Then adjust that view's frame in the viewDidLayoutSubviews of the pushed view controller to avoid having content permanently beneath the toolbar using the top/bottomLayoutGuide of the view controller.
I built a new project using your Gist, and I encased the UITabBarController in a UINavigationController:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
UITabBarController* tabController = [[UITabBarController alloc] init];
tabController.viewControllers = #[
[[UINavigationController alloc] initWithRootViewController:[[FirstViewController alloc] init]],
[[UINavigationController alloc] initWithRootViewController:[[FirstViewController alloc] init]]
];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:tabController];
[navController setNavigationBarHidden:YES];
self.window.rootViewController = navController;
return YES;
}
And to show the SecondViewController, here is what I did:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
SecondViewController* controller = [[SecondViewController alloc] init];
// Reaching the UITabBarViewController's parent navigationController
[self.parentViewController.navigationController pushViewController:controller animated:YES];
}
Finally, in the secondViewController:
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
self.view.backgroundColor = [UIColor redColor];
self.view.clipsToBounds = YES;
// The following line only works in iOS7
if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
self.edgesForExtendedLayout = UIRectEdgeNone;
}
[self.navigationItem setRightBarButtonItem:[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:nil action:nil]];
UIBarButtonItem * logoutButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemReply target:nil action:nil];
NSMutableArray * arr = [NSMutableArray arrayWithObjects:logoutButton, nil];
[self setToolbarItems:arr animated:YES];
[self.navigationController setNavigationBarHidden:NO animated:YES];
[self.navigationController setToolbarHidden:NO animated:YES];
}
- (void)viewWillDisappear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:YES animated:YES];
[self.navigationController setToolbarHidden:YES animated:YES];
}
Here's what it does look:
EDIT: Changed the example and changed the screenshot. Made the example iOS6 compatible.
I manually manage hide/unhide of bottom-tab-bar along with fade animation by
...
[self.tabBarController.tabBar setHidden:NO];
[self.tabBarController.tabBar setAlpha:0.1];
[UIView animateWithDuration:0.2 animations:^{
[self.tabBarController.tabBar setAlpha:1.0];
}];
...
Bottom Toolbar on SecondVC was added in IB. No problem so far. Using Storyboard.
I think you can set SecondController's edgesForExtendedLayout to UIRectEdgeBottom.
This helps me:
Choose you view controller in storyboard -> Go to properties -> Uncheck "Adjust Scroll View Insets"
As #Leo Natan is pointing out, it seems as if hiding the tab bar and showing a toolbar is discouraged.
Nevertheless, there is a very easy solution that is working:
Just check "Under Opaque Bars" in the view controller properties in the storyboard as shown below:

iOS - how to dismiss keyboard?

In my app, I press a button and it pulls up a modal presentation sheet (for iPad). Within this modal view I have a scrollview within my main view, and 1 text field within my scroll view.
view controller
view
scrollview
text field
Nothing I have tried resigns the keyboard and I don't know why. The only thing that happens is the blinking cursor in the textfield goes away. My class is the delegate for the scrollview and text fields. Here is what I have tried:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
[self.titleTextField resignFirstResponder];
[self.titleTextField endEditing:YES];
[self.view endEditing:YES];
[self.view resignFirstResponder];
[self.scrollView endEditing:YES];
[self.scrollView resignFirstResponder];
}
The method does get called, but the keyboard doesn't go away. Can anyone help me or at least tell me why?
Here is how I present this modalpresentation view:
(it comes from a tableviewcontroller)
didSelectRowAtIndexPath
EditVideo *targetController = [self.storyboard instantiateViewControllerWithIdentifier:#"editVideo"];
targetController.delegate = self;
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:targetController];
navigationController.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:navigationController animated:YES completion:nil];
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
On the iPad for any any non-fullscreen presented ViewController, you must implement -(BOOL)disablesAutomaticKeyboardDismissal to return NO to dismiss the keyboard.
- (BOOL)disablesAutomaticKeyboardDismissal
{
return NO;
}
Once that is implemented, you can call [self.view endEditing:YES];.
Edit:
The other common cause of this problem is returning NO from - (BOOL)textFieldShouldEndEditing:(UITextField *)textField. Implement the method in the UITextFieldDelegate and have it return YES unconditionally to prove that it is not a factor.

UINavigationController as child of UINavigationController

I don't know if the title explains the question itself but here it is ...
I have a UINavigationController which is the parentViewController of a UINavigationController. The thing is the childViewController behaves strange, when I add it as a child it first has the gap for the statusBar (it doesn't occupy the entire screen) and if I "solve" that "bug" by hiding and showing the navigationBar, the gap goes away but now the child doesn't respect the frame I set manually.
Then I tried to continue and when I presented a modal on the child and dismiss it, the entire child goes away ...
What would be wrong there? The parent-child relationship with both containers or what?
Thanks in advice
EDIT: Here's an example project showing the strange behavior
http://www.mediafire.com/?8saa68daqfkf335
EDIT 2: I found a solution actually and I didn't find it really clear on Apple Docs, it says the childViewControllers take its frame from the parentViewController they belong to, but it doesn't say that if the parentViewController "reappears" (like a push on it) the childViewControllers get resized again by the parentViewController frame ... Hope this helps anyone
I believe it would be better to present the second navigation view controller as a modal view controller.
For example, replace your current presentController selector with something like:
- (void)presentController:(id)sender {
ChildViewController1 *cvc = [[ChildViewController1 alloc] initWithNibName:#"ChildViewController1" bundle:nil];
nc3 = [[UINavigationController alloc] initWithRootViewController:cvc];
nc3.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:nc3 animated:YES completion:nil];
UIBarButtonItem *i = [[UIBarButtonItem alloc] initWithTitle:#"X" style:UIBarButtonItemStyleBordered target:self action:#selector(close)];
cvc.navigationItem.leftBarButtonItem = i;
}
Then, your close selector could become:
- (void)close {
[nc3 dismissViewControllerAnimated:YES completion:nil];
}
(though I'd recommend moving the creation of the button and handling the close actually in ChildViewController1.m).
Of course, this would take all the creation of the navigation controller off ViewController.m's viewDidLoad selector:
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor blueColor];
UIButton *b = [UIButton buttonWithType:UIButtonTypeRoundedRect];
b.frame = CGRectMake(0, 100, 100, 40);
[b setTitle:#"present" forState:UIControlStateNormal];
[b addTarget:self action:#selector(presentController:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:b];
}
Hope it works!

Resources