IOS - Issues with UITextField Inside A Toolbar - ios

I have a UIToolbar that I have programatically created that has a UITextField and UIButton added to it as separate subviews. The code below shows the method which creates the UIToolbar and returns the UIView.
- (UIToolbar *)createToolbar
{
//set background of toolbar
UIImage *rawBackground = [UIImage imageNamed:#"toolbarBackground.png"];
UIImage *toolBarBackground = [rawBackground stretchableImageWithLeftCapWidth:13 topCapHeight:22];
createPostBar = [[UIToolbar alloc] init];
createPostBar.frame = CGRectMake(0, 0, self.view.frame.size.width, 44);
[createPostBar setBackgroundImage:toolBarBackground forToolbarPosition:UIToolbarPositionAny barMetrics:UIBarMetricsDefault];
//add and syle all toolbar items
textView = [[HPGrowingTextView alloc] initWithFrame:CGRectMake(5, 6, 270, 40)];
textView.contentInset = UIEdgeInsetsMake(0, 5, 0, 5);
textView.minNumberOfLines = 1;
textView.maxNumberOfLines = 6;
textView.returnKeyType = UIReturnKeyDefault;
textView.font = [UIFont systemFontOfSize:15.0f];
textView.textColor = [UIColor blackColor];
textView.text = #"";
textView.delegate = self;
textView.internalTextView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, 0, 0);
textView.backgroundColor = [UIColor whiteColor];
UIImage *postBtnBackground = [UIImage imageNamed:#"postButton.png"];
UIImage *rawEntryBackground = [UIImage imageNamed:#"postFieldBackground.png"];
UIImage *entryBackground = [rawEntryBackground stretchableImageWithLeftCapWidth:13 topCapHeight:22];
toolbarOverlay = [[UIImageView alloc] initWithImage:entryBackground];
toolbarOverlay.frame = CGRectMake(4, 0, 278, 44);
UIButton *postButton = [UIButton buttonWithType:UIButtonTypeCustom];
[postButton addTarget:self
action:#selector(btnEdit:)
forControlEvents:UIControlEventTouchDown];
[postButton setBackgroundImage:postBtnBackground forState:UIControlStateNormal];
postButton.frame = CGRectMake(280, 5, 35.0, 35.0);
[createPostBar addSubview:textView];
[createPostBar addSubview:toolbarOverlay];
[createPostBar addSubview:postButton];
createPostBar.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
return createPostBar;
}
I then add the UIToolbar to a UITextField as its accessory view when the text field is clicked.
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
if (textField.tag <= 2)
{
textField.inputAccessoryView = [self createToolbar];
}
}
When the text field is clicked the keyboard pops up with the toolbar. Rate now the text field in the toolbar allows you to change the text of the text field that was clicked. Rate now when the text field is clicked the curser stays with in the clicked text field.
How can I make it so that the curser moves to the UITextField in the toolbar when the text field is clicked and no the original text field. Also, how do I disable editing of the text in the text field? I tried disabling user interactions but that made it so the text field was no longer clickable.

You probably shouldn't be using a text field to show your data, use a label instead (with a gesture recognizer).
To show your keyboard, don't use an accessory view, just add the toolbar as a subview and make the text field the first responder.
If you try to do it the way you describe it won't work because the accessory view will be removed when the original text field is no longer the first responder.
Finally, think about maybe using an alert view with a text field instead...

Related

How to I add a button on top of iCarousel?

I added the date label and the share button via code. Now I want to add a static button in the right top corner to open a slide out menu(I'm using MMDrawerController). If I'm adding the via code, it's moving with the carousel.
If I'm adding a button on the name label(My App) on the storyboard, it's not getting clicked and the carousel gesture is being registered instead of the button click.
How should I proceed to add a button for a slide out menu on the right ?
-(UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSInteger)index reusingView:(UIView *)view{
UIView *magView = nil;
CGFloat height = self.myCarousel.bounds.size.height;
CGFloat width = self.myCarousel.bounds.size.width;
//Magazine View
magView = [[UIView alloc] initWithFrame:CGRectMake(0, 40, width/1.35, height/1.75)];
magView.backgroundColor = [UIColor clearColor];
UIImageView *magImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"4 1:2.jpg"]];
magImage.frame = CGRectMake(0, 0, width/1.35, height/1.75);
[magView addSubview:magImage];
//Date Label
UILabel *dateLabel = nil;
dateLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, height/1.7, width/4, height/25)];
dateLabel.backgroundColor = [UIColor clearColor];
dateLabel.text = #"12-03-2017";
dateLabel.font = [UIFont fontWithName:#"Roboto-Black" size:5];
dateLabel.textColor = [UIColor whiteColor];
//Share Button
UIButton *shareButton = nil;
shareButton = [[UIButton alloc] initWithFrame:CGRectMake(width/1.49, height/1.7, height/25, height/25)];
shareButton.backgroundColor = [UIColor clearColor];
[shareButton setBackgroundImage:[UIImage imageNamed:#"share_icon_1x"] forState:UIControlStateNormal];
[magView addSubview:dateLabel];
[magView addSubview:shareButton];
return magView;
}
Simulator
Storyboard
How do I proceed to add the button ?
Add button to storyboard and after adding carousel programmatically. add code to bring the button to top on view.
[self.view bringSubviewToFront:button];
if you are adding it programmatically then just after [self.view addSubview:carousel];
call [self.view bringSubviewToFront:button](make sure button is added on view before calling it)
I solved the issue. Instead of taking the view of the ViewController I dragged/dropped another view onto the ViewController and displayed the carousel on it. Now I can set the button easily. Thanks for the help though. Cheers
It will help you
[xyzButton.superview setUserInteractionEnabled:YES];
:)

UISearchBar Layout Issues (iOS 8)

I'm making what should be a simple change to an app to add a UISearchBar component, but am getting some fairly strange layout quirks in the UI. It's perhaps easier to illustrate using pictures.
Here's what the component looks like when it doesn't have focus:
Note that the icon and the placeholder text are too far over, and the placeholder text is too far up. And here's what happens when I tap on the field:
The icon is now in the correct place, but the placeholder text is now too far to the left and overlapping with the icon. What gives?
When the field loses focus, it reverts to its original layout. Unless I type some text into it first, in which case it retains the second layout.
The code I'm using to set up the UISearchBar isn't doing anything special:
UIView* containerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 44)];
containerView.backgroundColor = UI_COLOR_NAV_TITLEBAR;
searchField = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, containerView.frame.size.width - 40, 44)];
searchField.placeholder = #"search all items";
searchField.searchBarStyle = UISearchBarStyleMinimal;
searchField.showsBookmarkButton = NO;
searchField.showsCancelButton = NO;
searchField.showsScopeBar = NO;
searchField.showsSearchResultsButton = NO;
UITextField* textSearchField = [searchField valueForKey:#"_searchField"];
searchField.backgroundColor = [UIColor clearColor];
textSearchField.textColor = UI_COLOR_NAV_TEXT;
searchField.delegate = self;
[containerView addSubview:searchField];
//...
I want the UISearchBar to always appear as in the second example, except obviously without the text field overlapping with the icon. Is there a simple solution to this issue that I've overlooked?
Try following code for searchField..
[searchField setLeftViewMode:UITextFieldViewModeNever];
[searchField setRightViewMode:UITextFieldViewModeNever];
[searchField setBackground:[UIImage imageNamed:#"searchicon.png"]];
Last is to show icon at left side, use image for that.

How can I change size of UINavigationBar in UINavigationViewController in iOS 8?

What is the proper way to change height of navigation bar?
I need to create custom title in navigation bar, it should contains two UILabels one above other. The Title should be resized to fit those UILabels.
Should I override sizeThatFits: method in my custom TitleView, would other buttons correctly change to fit that size? How can I change a size of NavigationBar?
That is what I need to create using latest SDK features.
Create the following class category (you can create it in your implementation file):
#import "objc/runtime.h"
#interface UINavigationBar (CustomHeight)
- (void)setHeight:(CGFloat)height;
#end
static char const *const kHeight = "Height";
#implementation UINavigationBar (CustomHeight)
- (void)setHeight:(CGFloat)height
{
objc_setAssociatedObject(self, kHeight, #(height), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (NSNumber *)height
{
return objc_getAssociatedObject(self, kHeight);
}
- (CGSize)sizeThatFits:(CGSize)size
{
CGSize newSize;
if (self.height) {
newSize = CGSizeMake(self.superview.bounds.size.width, [self.height floatValue]);
} else {
newSize = [super sizeThatFits:size];
}
return newSize;
}
#end
And after that, simply call [self.navigationController.navigationBar setHeight:100.0] in your viewDidLoad or where you need it. Works in both iOS 7.1 and 8.1.
Disclaimer: Any alteration of the API and its functions is prone to future issues with new OS releases! Apple does not intend to allow us to change the navigation bar height (except for some rare instances) so use any solution wisely after assessing the risks vs advantages.
Looking at that design that you posted, I don't have the impression that the bar is really higher than the standard 44pt. Please note that starting with iOS7 the status bar is integrated into the same bar and the 20pt of the status bar is added to the total height.
IMHO, the only problem you need to solve is to stack the title/subtitle, and that can be easily done with a custom titleView, as Kampai has demonstrated.
Add custom view for both navigation title and navigation right bar button.
Here how you can add title view like above.
// Custom view for navigation title.
UIView *customTitleView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 44)];
UILabel *label1 = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 22)];
label1.text = #"Stasik";
label1.font = [UIFont fontWithName:#"HelveticaNeue-Light" size:20];
label1.textAlignment = NSTextAlignmentCenter;
[customTitleView addSubview:label1];
UILabel *label2 = [[UILabel alloc] initWithFrame:CGRectMake(0, 22, 100, 22)];
label2.text = #"Stasik iPhone";
label2.font = [UIFont fontWithName:#"HelveticaNeue-Light" size:16];
label2.textAlignment = NSTextAlignmentCenter;
label2.textColor = [UIColor darkGrayColor];
[customTitleView addSubview:label2];
self.navigationItem.titleView = customTitleView;
// Custom view for right navigation.
UIButton *upButton = [UIButton buttonWithType:UIButtonTypeCustom];
upButton.frame = CGRectMake(0, 0, 20, 44);
[upButton setImage:[UIImage imageNamed:#"up"] forState:UIControlStateNormal];
[upButton addTarget:self action:#selector(upButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *upButtonBarItem = [[UIBarButtonItem alloc] initWithCustomView:upButton];
UIButton *downButton = [UIButton buttonWithType:UIButtonTypeCustom];
downButton.frame = CGRectMake(0, 0, 20, 44);
[downButton setImage:[UIImage imageNamed:#"down"] forState:UIControlStateNormal];
[downButton addTarget:self action:#selector(downButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *downButtonBarItem = [[UIBarButtonItem alloc] initWithCustomView:downButton];
// Remove trailing space for right view.
UIBarButtonItem *nagativeSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil];
nagativeSpace.width = -11;
self.navigationItem.rightBarButtonItems = #[nagativeSpace, upButtonBarItem, downButtonBarItem];
// Left item
UIButton *backButton = [UIButton buttonWithType:UIButtonTypeCustom];
backButton.frame = CGRectMake(0, 0, 40, 44);
[backButton setImage:[UIImage imageNamed:#"back"] forState:UIControlStateNormal];
[backButton addTarget:self action:#selector(backButtonTapped:) forControlEvents:UIControlEventTouchUpInside];
// Remove leading space for left view.
nagativeSpace.width = -15;
UIBarButtonItem *backButtonBarItem = [[UIBarButtonItem alloc] initWithCustomView:backButton];
self.navigationItem.leftBarButtonItems = #[nagativeSpace, backButtonBarItem];
OutPut:
Arrow images are different than OP's requirement but it serves layout for navigation views.
From above code make change in nagativeSpace.width value to arrange buttons with accurate distance from left as well as right margins.

View with subviews in a uinavigationbar and uitoolbar

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];
}

UITextField rightViewMode not working correctly

I need to make a custom clear button on a UITextField, so I am using the rightView. Code is below:
UIImage *clearImage = [[UIImage imageNamed:#"search-clear.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0.0,0.0, 0.0, 0.0)];
UIImageView *clearImageView = [[UIImageView alloc]initWithImage:clearImage];
UIButton *clearButton = [UIButton buttonWithType:UIButtonTypeCustom];
clearButton.frame = clearImageView.frame;
[clearButton setBackgroundImage:clearImage forState:UIControlStateNormal];
clearButton.backgroundColor = [UIColor clearColor];
self.emailTextField.rightViewMode = UITextFieldViewModeWhileEditing;
self.emailTextField.rightView = clearButton;
self.emailTextField.clearButtonMode = UITextFieldViewModeNever;
However, the button is not showing up at the correct times. It shows when the text field is in focus only with text length 0. As soon as I start typing it disappears. I need to figure out how to replace and duplicate the clear button, so that it shows when the string is at least 1 character.
you can't display both at the same time , but you can do it like this
UITextField * textfield = [[UITextField alloc] initWithFrame:CGRectMake(10, 100, 300, 40)];
[textfield setBorderStyle:UITextBorderStyleRoundedRect];
UIImageView * imgvw = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"search.jpeg"]];
[imgvw setFrame:CGRectMake(0, 0, 30, 30)];
[textfield setRightView:imgvw];
[textfield setRightViewMode:UITextFieldViewModeUnlessEditing];
[textfield setClearButtonMode:UITextFieldViewModeWhileEditing];
[self.view addSubview:textfield];

Resources