I am creating 5 buttons dynamically in my project.
Now I want code for each of the dynamic buttons to move to the next screen when I click a button.
If you have sample example same like my requirement then please post here.
I know its very easy for drag and drop control to connect next form but I want to do that dynamically.
Code I have so far:
for (i = 1; i <= 5; i++) {
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeCustom];
aButton.frame = CGRectMake(xCoord, yCoord, buttonWidth, buttonHeight);
[
aButton addTarget:self action:#selector(whatever:)
forControlEvents:UIControlEventTouchUpInside
];
[scrollView addSubview:aButton];
yCoord += buttonHeight + buffer;
}
You can push a new UIViewController programmatically
Refer to this answer: Push another View in UINavigationController?
See this answer for using Nibs: Navigation Controller Push View Controller
UIViewController *viewController = [[UIViewController alloc] init];
[self.navigationController pushViewController:viewController animated:YES];
Related
I have the following storyboard. Navigating to Class VC, I need to create custom buttons at the top of the VC and I think it will be beneath the Top Navigation Bar Controller. How do I make my custom buttons on top of the Navigation Bar Controller and clickable. I have already make the Top Navigation Bar appearance to be transparent.
I have the following code that is working and the layout is at the following pic However this is not my desired layout. It is located somewhere below the Transparent Navigation Bar controller area.
//--- customizeable button attributes
CGFloat X_BUFFER = 0.0; //--- the number of pixels on either side of the segment
CGFloat Y_BUFFER = 0.0; //--- number of pixels on top of the segment
CGFloat HEIGHT = 50.0; //--- height of the segment
//--- customizeable selector bar attributes (the black bar under the buttons)
CGFloat SELECTOR_Y_BUFFER = 0.0; //--- the y-value of the bar that shows what page you are on (0 is the top)
CGFloat SELECTOR_HEIGHT = 44.0; //--- thickness of the selector bar
CGFloat X_OFFSET = 8.0; //--- for some reason there's a little bit of a glitchy offset. I'm going to look for a better workaround in the future
CGFloat numControllers = 7.0;
-(void)setupSegmentButtons
{
navigationView = [[UIView alloc]initWithFrame:CGRectMake(0,0,self.view.frame.size.width,52)];
navigationView.backgroundColor = [UIColor greenColor];
[self.view addSubview:navigationView];
//——Format Some Dates
for (int i = 0; i<numControllers; i++) {
UIButton *button = [[UIButton alloc]initWithFrame:CGRectMake(i*(self.view.frame.size.width/numControllers), Y_BUFFER, (self.view.frame.size.width/numControllers),HEIGHT)];
[navigationView addSubview:button];
NSString *lblDate = [datelblFormat stringFromDate:[calendar dateFromComponents:comps]];
UILabel *firstLineButton = [[UILabel alloc] initWithFrame:CGRectMake(-4,0,self.view.frame.size.width/numControllers,30)];
firstLineButton.text = lblDate;
[button addSubview:firstLineButton];
NSString *lblDay = [daylblFormat stringFromDate:[calendar dateFromComponents:comps]];
UILabel *secondLineButton = [[UILabel alloc] initWithFrame:CGRectMake(-4,30,self.view.frame.size.width/numControllers,15)];
secondLineButton.text = lblDay;
[button addSubview:secondLineButton];
button.tag = i; //--- IMPORTANT: if you make your own custom buttons, you have to tag them appropriately
button.backgroundColor = [UIColor brownColor];//— buttoncolors
[button addTarget:self action:#selector(tapSegmentButtonAction:) forControlEvents:UIControlEventTouchUpInside];
++comps.day;
}
[self setupSelector];
}
//--- sets up the selection bar under the buttons on the navigation bar
-(void)setupSelector {
selectionBar = [[UIView alloc]initWithFrame:CGRectMake(self.view.frame.size.width/numControllers, Y_BUFFER, (self.view.frame.size.width/numControllers),HEIGHT)];
selectionBar.backgroundColor = [UIColor colorWithRed:189.0f/255.0f green:225.0f/255.0f blue:255.0f/255.0f alpha:0.6];
[navigationView addSubview:selectionBar];
}
I manage to move the custom buttons to the top by changing the Y Coordinates and I got the following results. Its not ideal cause I need the brown colour to be all the way to the edge of the phone especially iPhoneX and the buttons to be clickable.
I was not able to comment that's why suggesting this as an answer.
I think you should present your view controller instead of pushing it.
[self presentViewController:#"your view controller" animated:YES completion:nil];
Answer:
To hide the navigation bar at the current VC or the 1st VC
-(void)viewWillAppear:(BOOL)animated{
[[self navigationController] setNavigationBarHidden:YES animated:YES];
}
To UNHIDE the navigation bar on subsequent VC or the 2nd VC. At the 1st VC, apply the following code.
-(void)viewDidDisappear:(BOOL)animated{
[[self navigationController] setNavigationBarHidden:NO animated:YES];
}
Then the buttons will be clickable.
I have a uisegementcontrol and a uibarbutton that gets added to the navigation bar of the navigation controller. When I push to the next view, however, I want them to be removed. I tried several approaches, but nothing seems to be removing them. One approach was using viewWillDisappear and having the segementcontrol and the bar button removedFromSuperView. Another was to call the removeFromSuperView from the method that pushes to the next scene. Nothing seems to be working. I've actually been stuck on this for a really long time!
Also, the view controller "X" that has the segement control and the bar button is presented through a presentViewController. X then pushes the other view controller.
Here is the code for the segement control
NSArray *headers = #[#"Tracks", #"Playlists"];
self.savedMusic = [[UISegmentedControl alloc] initWithItems:headers];
CGSize size = self.view.frame.size;
CGRect segFrame = CGRectMake(80, 5, size.width - 140, 35);
self.savedMusic.backgroundColor = [UIColor blackColor];
self.savedMusic.frame = segFrame;
self.savedMusic.tag =1;
[self.savedMusic setTitle:#"Tracks"
forSegmentAtIndex:0];
[self.savedMusic setTitle:#"Playlists"
forSegmentAtIndex:1];
[self.savedMusic addTarget:self
action:#selector(whatToDisplay)
forControlEvents:UIControlEventValueChanged];
self.savedMusic.selectedSegmentIndex = 0;
[self.navigationController.navigationBar addSubview:self.savedMusic];
Here is the code for the viewWillDisapear
[super viewWillDisappear:animated];
self.navigationController.navigationBar.barStyle = UIBarStyleDefault;
self.navigationItem.leftBarButtonItem = nil;
[self.savedMusic removeFromSuperview];
And here is the code for the method that switches to the new view
PlaylistTracksTableViewController *vc = [[PlaylistTracksTableViewController alloc] init];
[self.savedMusic removeFromSuperview];
[[self.navigationController.navigationBar viewWithTag:1] removeFromSuperview];
self.navigationItem.leftBarButtonItem = nil;
[self.navigationController pushViewController:vc animated:YES];
The problem is that what you are doing is not how you manipulate the contents of the navigation bar. Do not talk to self.navigationController.navigationBar. Instead, each view controller should set its own self.navigationItem, and the runtime will use that to populate the navigation bar for that view controller.
I have a Tab-Bar button on a View Controller.I want when a user press that button a sub-view sides from the corner and shows the list of buttons for specified actions and on pressing tab bar button again sub-view should slide back and disappear.This sub-view should be shown on small frame of main View. How i can accomplish this task?
Add a custom action to that button.
when a user presses the button check to see if the buttons view's origin is within the bounds of your main view. if it's not, slide it in, else slide it out.
I would probably do something like that:
// Call this one on viewDidLoad
-(void)createMenuButton {
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
[button addTarget:self action:#selector(toggleMenu) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *item = [[UIBarButtonItem alloc] initWithCustomView:button];
self.navigationItem.rightBarButtonItem = item;
}
// Make sure the menuView property was added as subview of self.view
-(void)toggleMenu {
if (CGRectContainsPoint(self.view.bounds, self.menuView.frame.origin)) {
[UIView animateWithDuration:.35
animations:^{
CGRect rect = self.menuView.frame;
rect.origin.x -= self.menuView.frame.size.width;
self.menuView.frame = rect;
}];
} else {
[UIView animateWithDuration:.35
animations:^{
CGRect rect = self.menuView.frame;
rect.origin.x += self.menuView.frame.size.width;
self.menuView.frame = rect;
}];
}
}
Hope this helps :)
My goal: To have a sliding menu that will push the current view of my app when it opens.
I've subclassed my UINavigationController in order to create custom "back" buttons and the sliding from the right menu. To do so, inside my subclassed UINavigationController i'm changing the x origin of the current UIViewController (self.view.fram) to a value that will move it to the left x = -100; and by doing so i'm exposing the right menu.
After completing the above I've found out that by moving self.view I'm also moving the touchable area so the button on the right menu won't be accesible \ clickable.
I've read a lot about pointInside and hitTest that can help me achieve what i want but still couldn't implement it in a way that will fit my needs.
I'm aware that there are a 1000 open source projects on github that do exactly what I want but 'd like to write it my self and understand it better.
Thanks.
NavControllerSubCls.h:
#interface NavControllerSubCls : UINavigationController <UINavigationControllerDelegate>
#property (nonatomic, strong) UIView *testView;
#property (nonatomic, strong) UIButton *rightMenuBtn;
#end
NavControllerSubCls.m:
-(void)viewDidLoad
{
[super viewDidLoad];
UIView *navBar = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 320, 41)];
navBar.backgroundColor = [UIColor blueColor];
UIImageView *bkrNavBar = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 320, 39)];
[navBar addSubview:bkrNavBar];
_rightMenuBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[_rightMenuBtn setFrame:CGRectMake(240, 20, 52, 19)];
[_rightMenuBtn setTitle:#"Click" forState:UIControlStateNormal];
[_rightMenuBtn addTarget:self action:#selector(showRightMenu) forControlEvents:UIControlEventTouchUpInside];
[navBar addSubview:_rightMenuBtn];
_testView = [[UIView alloc]initWithFrame:CGRectMake(300, 20, 120, 100)];
_testView.backgroundColor = [UIColor greenColor];
UIButton *testBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
testBtn.frame = CGRectMake(0, 0, 120, 100);
[testBtn addTarget:self action:#selector(doSomething) forControlEvents:UIControlEventTouchUpInside];
[_testView addSubview:testBtn];
[self.view addSubview:_testView];
[self.view addSubview:navBar];
[self.view insertSubview:_testView aboveSubview:self.view];
}
-(void)doSomething
{
NSLog(#"I'm Working!");
}
- (void)showRightMenu
{
CGRect frame = self.view.frame;
frame.origin.x = -100;
self.view.frame = frame;
}
You mean like the Facebook app? I think a better design would be to have a parent view controller that manages the sliding and two child view controllers, one for the menu and one for the content.
EDIT
The SlidingViewController has two child view controllers: a ContentViewController that takes up all the space and a MenuViewController underneath the ContentViewController.
The SlidingViewController only manages the sliding interaction, whether that's coming from a pan gesture or from a method call. When it's time to show the menu, the SlidingViewController will shift the ContentViewController so that the MenuViewController is visible (by changing the transform or frame property).
The ContentViewController and MenuViewController are just containers for the real view controllers. You use these containers so that you can do whatever you want to them (say if you want to do some really funky animation) without affecting the real view controllers.
So the view controller hierarchy would look like this:
SlidingViewController
/ \
MenuViewController ContentViewController
| |
UITableViewController, etc. UINavigationController, etc.
I'm creating a dynamic number of buttons(eventually, these will be placed inside a horizontal scroll view), and I'm displaying a popover when a button is pressed, but I need to set the popover to appear just to the right of the selected button, but at the moment, the popover appears at the same place every time...
This is what I'm trying:
for (int i=0; i < 10; i++) {
childButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
childButton.frame = CGRectMake(100*i, 170, 100, 30);
[childButton setTitle:#"Test" forState:UIControlStateNormal];
[childButton addTarget:self action:#selector(presentPopoverMenu) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:childButton];
}
Ultimately I'm going to create two rows of images, but this is just for testing...
-(void)presentPopoverMenu/*:(id)sender*/
{
MenuPickerController *mp = [[MenuPickerController alloc] init];
popoverMenu = [[UIPopoverController alloc] initWithContentViewController:mp];
popoverMenu.popoverContentSize = CGSizeMake(290, 300);
[popoverMenu presentPopoverFromRect:[childButton bounds]
inView:childButton
permittedArrowDirections:UIPopoverArrowDirectionAny
animated:NO];
}
I'm thinking that it's probably just taking the value from last button, but I'm not sure, how I would do this otherwise...
Of course it uses last button value, because your ivar childButton points on it. Take not childButton but sender. Uncomment it and use. Also selector will be #selector(presentPopoverMenu:).