View with subviews in a uinavigationbar and uitoolbar - ios

I really need your help with this one (first post on SO -- be gentle):
I have two dynamic UIButtons which I would like to have centered in a UIView, which in turn should be centered in a UINavigationbar and UIToolbar. I can't - despite a lot of Googling - seem to figure out a proper way to do this.
This is what I've done so far:
In viewDidLoad, I add the two buttons as subviews and set the view as the UINavigationbar's titleView
self.myClass.viewForTitleAndButton = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 120, 32)];
[self.myClass.viewForTitleAndButton setBackgroundColor:[UIColor blackColor]];
[self.myClass.viewForTitleAndButton addSubview:self.myClass.myButton];
[self.myClass.viewForTitleAndButton addSubview:self.myClass.myOtherButton];
self.navigationItem.titleView = self.myClass.viewForTitleAndButton;
In a method being triggered when I press certain buttons, I set the title (and bounds) of one of the buttons depending on what's clicked:
CGSize titleSize = [title sizeWithAttributes:#{NSFontAttributeName : [UIFont italicSystemFontOfSize:17.0]}];
CGSize screenSize = [UIScreen mainScreen].bounds.size;
CGFloat newX = (screenSize.width - titleSize.width) / 2;
CGRect buttonFrame = self.myClass.myButton.frame;
//Removing the line below doesn't do any difference at the moment
self.myClass.myButton.bounds = CGRectMake(newX, buttonFrame.origin.y, titleSize.width+8, buttonFrame.size.height);
[self.myClass.myButton setTitle:title forState:UIControlStateNormal];
NSLog(#"Title: %#", title);
//title is a NSString that changes depending on what is clicked. I am 100% sure it changes as I can see it in the log every time the method is triggered.
The problem is that the title of myButton is not changed. It worked before with the very same button when it was placed in a different spot and not as a subview.
Q1: What am I missing to make the title of the button change?
Q2: Is adding the buttons as subViews to a view that is then placed in the navigationbar and toolbar respectively a sound way to accomplish what I want?
This is really bugging me, any pointers in the right direction is much appreciated.

I don't think you can add a button which is already an outlet of a view controller. Thinking in another way, a button(view) can only has one superview.
Create button dynamically for the title view.
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *iv = [[UIView alloc]initWithFrame:CGRectMake(0, 0, 160, 44)];
iv.backgroundColor = [UIColor greenColor];
titleButton = [UIButton buttonWithType:UIButtonTypeCustom];
titleButton.frame = CGRectMake(0, 0, 120, 44);
[titleButton setTitle:#"test" forState:UIControlStateNormal];
[titleButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
[iv addSubview:titleButton];
self.navigationItem.titleView = iv;
}
//some event to change the button title
- (void)click:(UIButton *)button
{
[titleButton setTitle:#"I changed" forState:UIControlStateNormal];
}

Related

UIBarButtonItem Target Method is not working

Actually i want to place image and label on the toolbar as a UIBarButtonItem and provide a clickable effect to that Button.
So what i have done here is I have created one custom view and placed Image and Label on the same custom view and finally placed this custom view as UIBarButtonItem CustomView.
But when i set target and action for the same UIBarButtonItem, it is not calling the selector method.
The entire code is below.
Can anybody suggest me what's the mistake in my code ? and is there any other approach to achieve the same ????
Early suggestions would be much appreciated.
- (void)viewDidLoad
{
[super viewDidLoad];
[self.navigationController setToolbarHidden:NO];
UIView *customView = [[UIView alloc]
initWithFrame:CGRectMake(0,0,self.navigationController.toolbar.frame.size.width,self.navigationController.toolbar.frame.size.height)];
customView.backgroundColor = [UIColor colorWithRed:62.0/255.0 green:187.0/255.0 blue:150.0/255.0 alpha:1.0];
[self.navigationController.toolbar addSubview:customView];
UIImageView *imgView = [[UIImageView alloc]initWithFrame:CGRectMake(60,0,44,44)];
imgView.image = [UIImage imageNamed:#"documentImage.png"];
[customView addSubview:imgView];
UILabel *lbl = [[UILabel alloc]initWithFrame:CGRectMake(104,0,145,44)];
lbl.text = #"Scan Document";
lbl.textAlignment = NSTextAlignmentLeft;
[customView addSubview:lbl];
UIBarButtonItem *bar = [[UIBarButtonItem alloc]initWithCustomView:customView];
bar.target = self;
bar.action = #selector(scanDocument);
self.toolbarItems = [NSArray arrayWithObjects:bar, nil];
}
If you want to create button right hand side here is the code. i have already implemented it and working fine.
//Button Right side
UIImage *imgFavRest = [UIImage imageNamed:#"documentImage.png"];
UIButton *cart = [UIButton buttonWithType:UIButtonTypeCustom];
[cart setImage:imgFavRest forState:UIControlStateNormal];
cart.frame = CGRectMake(0, 0, imgFavRest.size.width, imgFavRest.size.height);
[cart addTarget:self action:#selector(showCart) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *rightBtn = [[UIBarButtonItem alloc] initWithCustomView:cart];
self.navigationItem.rightBarButtonItem = rightBtn;
Then use method like this . that's all
-(void)cartItemCount{
// Method
}
float textwidth = 50; // according to your text
UIImage *image = [UIImage imageNamed:#"logout"];
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
btn.bounds = CGRectMake( 10, 0, image.size.width+textwidth, image.size.height );
[btn addTarget:self action:#selector(scanDocument) forControlEvents:UIControlEventTouchUpInside];
[btn setImage:image forState:UIControlStateNormal];
[btn setTitle:#"test" forState:UIControlStateNormal];
[btn setTitleEdgeInsets:UIEdgeInsetsMake(0.0, 5.0, 0.0, 0.0)];
//Adjust the coordinates and size of your button as your requirement.This is a sample code to guide you.
//PS:Take a UIButton in the nib file>Make it a custom button>Connect the IBOutlet to your custom button in the nib file.Thats it.
UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithCustomView:btn];
self.navigationItem.rightBarButtonItem = rightButton;
I see very complicated answers, all of them using code. However, if you are using Interface Builder, there is a very easy way to do this:
Select the button and set a title and an image. Note that if you set
the background instead of the image then the image will be resized if
it is smaller than the button.IB basic image and title
Set the position of both items by changing the edge and insets. You
could even control the alignment of both in the Control section.
IB position set IB Control set
You could even use the same approach by code, without creating UILabels and UIImages inside as other solutions proposed. Always Keep It Simple!
EDIT: Attached a small example having the 3 things set (title, image and background) with correct insets Button preview
Note:: UIBarButtonItem inherits from UIBarItem and NSObject so it doesn't know anything about touches. It would be nice if the docs mentioned that the action and target properties only apply if the custom view is a UIButton.

Add a view at the top of another view iOS

I need help. I'm designing my UI, and I have been using the properties FRAME and CENTER to layout my views. Both of those are so much helpful to me. I also use the technique of adding my elements as subview of UIViews container.
But, right now, I want to place a UIView at the top of another. Please take a look at my picture. The buttons at the bottom of the screen is already set and is perfect right now, I'm only having a hard time to place my UIView (a container of my textfields) above the button/divider.
I'm only starting in iOS, I think 1 month plus already. I know basics of constraints programmatically but I don't want to use this for now as much as possible.
PS. I make my screen programmatically.
Sample of my code in this screen
// start adding container
UIView *container2 = [[UIScrollView alloc] init];
container2.frame = CGRectMake(0, 0, [TPRConstants screenWidth] * 0.95, heightOfScrollView);
container2.backgroundColor = [UIColor blueColor];
container2.contentSize = CGSizeMake([TPRConstants screenWidth] * 0.95, 250);
[self.view container2];
// stuffs and subviews/textfields inside the container
self.phoneTextField = [[UITextField alloc] init];
_phoneTextField.frame = CGRectMake(0, 200, scrollView.frame.size.width, 50);
_phoneTextField.delegate = self;
_phoneTextField.borderStyle = UITextBorderStyleNone;
_phoneTextField.background = [UIImage imageNamed:#"textfieldLogIn.png"];
_phoneTextField.backgroundColor = [UIColor clearColor];
[_phoneTextField setKeyboardType:UIKeyboardTypeNumberPad];
[container2 addSubview:_phoneTextField];
// add container for divider and log in button
UIView *container = [[UIView alloc] init];
container.frame = CGRectMake(0, 0, [TPRConstants screenWidth], 80);
container.backgroundColor = [UIColor whiteColor];
container.center = CGPointMake([TPRConstants screenWidth] * 0.50, [TPRConstants screenHeight] - container.frame.size.height/2);
[self.view addSubview:container];
// add divider
UIImageView *divider = [[UIImageView alloc] initWithFrame:CGRectMake(0, 10, container.frame.size.width, 5)];
divider.image = [UIImage imageNamed:#"dividerCP.png"];
divider.backgroundColor = [UIColor clearColor];
divider.contentMode = UIViewContentModeCenter;
[container addSubview: divider];
// add save login
UIButton *saveBtn = [UIButton buttonWithType:UIButtonTypeCustom];
saveBtn.frame = CGRectMake(0, 0, container.frame.size.width * 0.95, 50);
saveBtn.center = CGPointMake(container.frame.size.width /2 , (container.frame.size.height - saveBtn.frame.size.height/2) - 10 );
[saveBtn addTarget:self action:#selector(saveBtnClick:) forControlEvents:UIControlEventTouchUpInside];
[saveBtn setBackgroundImage:[UIImage imageNamed:#"logoutupCP.png"] forState:UIControlStateNormal];
[saveBtn setTitle:#"Save" forState:UIControlStateNormal];
[saveBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[saveBtn setTitleColor:[UIColor blackColor] forState:UIControlStateHighlighted];
[saveBtn setBackgroundImage:[UIImage imageNamed:#"logoutdownCP.png"] forState:UIControlStateHighlighted];
[container addSubview: saveBtn];
In iOS everything in a view is added as a stack i.e on top of each other. So your button will always be on top of the divider as it is added last.
If you try your solution now on several screens, you will find that all of the items will be in different positions.
So you have to add constraints.
The easiest way is via storyboard.
Keep your textfields in one view and your button and divider in another view and add a vertical spacing constraint between both views.
Note: Ofcourse you have to add all the required trailing, leading, top and bottom constraints on each textField and the container views and separator image in view plus center horizontally and vertically constraints to the button.
If you wish to place a UIView at the base of phoneTextField use the maximum y position of phoneTextField for the y origin position of the UIView.
UIView *newView = [[UIView alloc] initWithFrame:CGRectMake(0,CGRectGetMaxY(phoneTextField.frame)+0,[TPRConstants screenWidth],50);
newView.backgroundColor = [UIColor blueColor];
[self.view addSubview:newView];
Then change the saveBtn frame to make space for newView:
saveBtn.frame = CGRectMake(0, CGRectGetMaxY(newView.frame), container.frame.size.width * 0.95, 50);

My UIView has a UIButton as one of it's subviews but not responding to events in objective-c

Here is my code. It has started to look crowded after an hour or 2 of trying to solve this issue. I've tried setting user interaction enabled to yes, I've tried just using a button alone and not making it the subview of another view.
Right now I have filterBar > filterBarContainer > filterButton.
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
self.navigationController.navigationBar.userInteractionEnabled = YES;
self.view.userInteractionEnabled = YES;
// Create filter bar with specified dimensions
UIView *filterBar = [[UIView alloc] initWithFrame:CGRectMake(0, 42, self.view.frame.size.width, self.navigationController.navigationBar.frame.size.height)];
[filterBar setUserInteractionEnabled:YES];
// Make it a subview of navigation controller
[[[self navigationController] navigationBar] addSubview:filterBar];
[filterBar setBackgroundColor:[[UIColor whiteColor] colorWithAlphaComponent:0.9f]];
[filterBar setTag:1];
// Reusable vars
// CGFloat filterBarX = filterBar.frame.origin.x;
//CGFloat filterBarY = filterBar.frame.origin.y;
CGFloat filterBarHeight = filterBar.frame.size.height;
CGFloat filterBarWidth = filterBar.frame.size.width;
// Create centre filter button with specified dimensions
UIView *filterButtonContainer = [[UIView alloc] initWithFrame:CGRectMake(0, 2, filterBarWidth / 2 - 30 , filterBarHeight - 10)];
[filterButtonContainer setUserInteractionEnabled:YES];
// Make it a subview of filter bar
[filterBar addSubview:filterButtonContainer];
[filterButtonContainer setBackgroundColor:[UIColor redColor]];
// Centre the button
[filterButtonContainer setCenter:[filterBar convertPoint:filterBar.center fromView:filterBar.superview]];
// Add button to filter button
UIButton *filterButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[filterButton setUserInteractionEnabled: YES];
[filterButton setFrame:CGRectMake(0, 0,40 , 20)];
[filterButton setTitle:#"test" forState:UIControlStateNormal];
[filterButtonContainer addSubview:filterButton];
[filterButton setBackgroundColor:[UIColor yellowColor]];
// self.filterButton = filterButton;
[filterButton addTarget:self action:#selector(filterButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
NSLog(#"dd");
filterButtonContainer.layer.borderColor = [UIColor blackColor].CGColor;
filterButtonContainer.layer.borderWidth = 1;
This is the method I'm trying to trigger.
- (void)filterButtonTapped:(UIButton *)sender
{
NSLog(#"filter button tapped");
UIActionSheet *filterOptions = [[UIActionSheet alloc] initWithTitle:#"Filter Garments"
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:#"Recommended", #"What's New", #"Price - High to Low", #"Price - Low to High", nil];
[filterOptions showInView:self.collectionView];
}
Most likely one of your parent views (superviews of your button) have a width or height that places the filter button outside of their area. The button is still displayed (if you don't define that the view should cut off subviews), but elements outside the view's area will not get any touch events. Check your superview's width and height.
You're adding filterBar as a subview of your navigationBar, but you're setting it's y-origin within navigationBar to 42. And then you're setting your filterButtonContainer's y-origin within the filterBar to 2. Assuming navigationBar's height is 44, most of the filterBar and the entirety of your filterButtonContainer and filterButton won't be within their navigationBar superview so the button wouldn't be selectable.
Edit: To make it selectable while keeping the positioning intact, I suggest adding the filter bar to self.view. For example, change:
[[[self navigationController] navigationBar] addSubview:filterBar];
to
[self.view addSubview:filterBar];

Adding a close button to the modal view that is partially off the view

I am trying to add a "X" button to the top of the modal view so if the user presses that it closes the modal view. I looked at the solution proposed here how to add close button to modal view corner which is presented in UIModalPresentationPageSheet?
But I have two follow up questions here as i am fairly new to ios programming
The solution proposed in the above page does not seem to work for me. I tried it with a normal button first in the viewDidLoad of the modal VC and I am seeing it appear only within the bounds of modal view and not outside as I want.
UIView *buttonView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 50)];
buttonView.backgroundColor = [UIColor brownColor];
CGRect buttonFrame = CGRectMake( 0, 0, 100, 50 );
UIButton *button = [[UIButton alloc] initWithFrame: buttonFrame];
[button setTitle: #"Close" forState: UIControlStateNormal];
[button setTitleColor: [UIColor redColor] forState: UIControlStateNormal];
[button addTarget:self
action:#selector(closeButtonPressed)
forControlEvents:UIControlEventTouchUpInside];
[buttonView addSubview: button];
CGRect parentView = self.view.superview.frame;
CGRect currentView = self.view.frame;
CGRect buttonViewFrame = buttonView.frame;
buttonViewFrame.origin = CGPointMake(parentView.origin.x - buttonViewFrame.size.width/2.0f, parentView.origin.y - buttonViewFrame.size.height/2.0f);
[buttonView setFrame:buttonViewFrame];
[self.view addSubview:buttonView];
what I am seeing is
How do I draw the "X" button do I use CGRect to draw it our or instead of adding a button in the above example should I just add a image with the "X" in it as the subview?
thanks in advance for the help
do like this, hope helps u :)
//adding button to your view
UIView *aView = [[UIView alloc]initWithFrame:CGRectMake(100, 200, 300, 350)];
aView.backgroundColor = [UIColor blueColor];
aView.tag = 100;
[self.view addSubview:aView];
UIButton *aButton = [UIButton buttonWithType:UIButtonTypeCustom];
[aButton setTitle:#"CLOSE" forState:UIControlStateNormal];
[aButton addTarget:self action:#selector(tapped:) forControlEvents:UIControlEventTouchUpInside];
aButton.frame = CGRectMake(aView.bounds.origin.x, aView.bounds.origin.y, 80, 30);// adjust with respect to bounds
aButton.backgroundColor = [UIColor redColor];
[aView addSubview:aButton];
[aView release]; //i am doing without ARC
The other option is to create a larger view and put your UITableView within this, along with your close button. The close button can then be at position (0,0) and the UITableView can start at (25,25).
This prevents complications - I have seen clipped views fail to recognise the touch outside of the main view, so your 50x50 button only has a touch area of 25x25.

Creating UIScrollView In Interface Builder Using Dynamic Content

I am a newcomer to the realm of iOS development.
I am trying to get the UIScrollView control to work and ran across the following question:
steps for creating UIScrollView with Interface Builder
I followed the steps outlined in the answer for this question and everything works as I want. However, this appears to create a statically-sized view that is scrolled. What I am really after is a dynamically sized view that may or may not be scrolled. For example, instead of the view with buttons, I put a single label for which I set the text and number of lines in the viewDidLoad method. The view that contains the label is set to a static size so the scroll viewer does not attempt to scroll and the content of the label spills off of the page.
What am I missing?
you need to set te content size of the scroll
CGPoint controlsCenter = ViewBottom.center;
if(Pointsvalue > 5)
{
controlsCenter.y += txtFldFrame1.frame.origin.y+20;
ViewBottom.center = controlsCenter;
[ScrollLag addSubview:ViewBottom];
}
[ScrollLag setContentSize:(CGSizeMake(0, controlsCenter.y+100))];
make sure your label height changes on entering text.......
The URL in my comment to the original question provides a solution to the issue I raised.
I have a dynamically sized UIScrollView in a project I am working on right now. This is what I did:
self.myScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 250, 748)];
[self.myScrollView setBackgroundColor:[UIColor blackColor]];
int heightCounter = 10;
UIButton *newButton = [UIButton buttonWithType:UIButtonTypeCustom];
newButton.frame = CGRectMake(10, heightCounter, 200, 40);
[newButton setBackgroundColor:[UIColor clearColor]];
[newButton addTarget:self action:#selector(someMethod:) forControlEvents:UIControlEventTouchUpInside];
[newButton setTitle:#"ButtonTitle" forState:UIControlStateNormal];
[newButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[self.myScrollView addSubview:newButton];
heightCounter += 50;
// add additional items to the myScrollView and remember to increase the heightCounter
self.myScrollView.contentSize = CGSizeMake(250, heightCounter);
self.myScrollView.scrollEnabled = YES;
[self.view addSubview:self.myScrollView];

Resources