How to change the Title View of the navigation bar into some Custom View and fill the original size - objective-c

I want to change the titleView of navigationBar with a regular text field. Then I want to set the textField size to fill the old "normal" titleView.
I can't seem to be able to do this in storyBoard. Dragging a text Field to the place where the navigation title View is doesn't work.
So I added stuff at
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
PO(self.navigationItem.titleView);
CGRect theFrame= self.navigationItem.titleView.frame;
self.navigationItem.titleView=self.searchBar;
//self.searchBar.frame = theFrame;
while (false);
...
It's working with one cached. That PO is a macro that print the content of the object. Turns out at viewDidAppear, self.navigationItem.titleView is null.
So while I can display the searchBar, I cannot make the searchBar "fill" it's space because I do not know the space is.
I prefer not to hard code it because you know, things may change in the future.
So what should I do?
I once saw codes where rather than setting the self.navigationItem.titleView, you would simply add subview to it. The problem with this approach even on viewDidAppear, self.navigationItem.titleView is 0.
I added these codes:
CGRect theFrame= self.navigationItem.titleView.frame;
CGRect theFrame2 = self.searchBar.frame;
CGRect theFrame3 = self.navigationController.navigationItem.titleView.frame;
And, I do not know how to nslog structure value, however, theFrame and theFrame3 are all 0

You can try this inside viewWillAppear:
UIView *customTitleView = [[UIView alloc]initWithFrame:CGRectMake((320-210)/2, 0, 210, 50)];
customTitleView.backgroundColor = [UIColor clearColor];
//create your UITextField or UILabel or other view and add as subview of customTitleView
self.navigationItem.titleView = customTitleView;

Related

Why UITextfield setBackground UIColor White turn to transparent?

I am writing an app and I want to make a textfield background turn white.
So far this is my code:
- (void)viewDidLoad
{
UITextField *txtfield = UsernameTextField;
[txtfield setBackgroundColor:[UIColor colorWithWhite:1 alpha:0.5] ];
txtfield.layer.borderColor = [UIColor blackColor].CGColor;
txtfield.layer.borderWidth = 1;
txtfield.borderStyle = UITextBorderStyleRoundedRect;
[super viewDidLoad];
// Do any additional setup after loading the view.
}
But this code have a result like this:
and i tried this code , to increast alpha
[txtfield setBackgroundColor:[UIColor colorWithWhite:1 alpha:0.8] ];
still the same
and also i see this post
iPhone UITextField background color
and i tried
but it still the same
Why textfield wont turn to white?
First thing first you should
[super viewDidLoad] should be the first statement in - (void)viewDidLoad after initialising parent child should do initialise.
Second
Please check the order of views put on view controller bring UsernameTextField to top of all views or you can call [self.view bringSubviewToFront:txtfield] in code
Third
Only by setting alpha to 1.0 you can see complete white background.
and finally is you still don't get it resolved then there is some changes you did in xib/storyboard view. So to reset just delete textfield and add it again.
In order to change background color it's important to set the border to None
txtfield.borderStyle = UITextBorderStyleNone;
Details: Changing background colour within a TextField in Interface Builder
iPhone UITextField background color
From Apple Doc:
When set, the image referred to by this property replaces the standard appearance controlled by the borderStyle property. Background images are drawn in the border rectangle portion of the text field. Images you use for the text field’s background should be able to stretch to fit.

UIButton inside UIView doesn't respond to touch events

I've put a UIButton inside a custom UIView and the button is not receiving any touch events (it doesn't get into the highlighted state, so my problem is not about being unable to wire up a touch inside up handler). I've tried both putting it into the XIB in Interface Builder, and also tried programatically adding the UIButton into the UIView seperately, both ended with no luck. All my views are inside a UIScrollView, so I first though UIScrollView may be blocking them, so I've also added a button programatically exactly the same way I add my custom view into UIScrollView, and the button worked, elimination the possibility of UIScrollView could be the cause. My View's hiearchy is like this:
The button is over the image view, and the front layer isn't occupying my button completely, so there's no reason for me not be physically interacting with the button. At my custom view's code side, I'm creating my view as such:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
UIView *sub = [[[NSBundle mainBundle] loadNibNamed:#"ProfileView" owner:self options:nil] objectAtIndex:0];
[self addSubview:sub];
[sub setUserInteractionEnabled:YES];
[self setUserInteractionEnabled:YES];
CALayer *layer = sub.layer;
layer.masksToBounds = YES;
layer.borderWidth = 5.0;
layer.borderColor = [UIColor whiteColor].CGColor;
layer.cornerRadius = 30.0;
/*layer.shadowOffset = CGSizeZero;
layer.shadowRadius = 20.0;
layer.shadowColor = [[UIColor blackColor] CGColor];
layer.shadowOpacity = 0.8;
*/
}
return self;
}
I've tried all combinations of setUserInteractionsEnabled, and had no luck. (Yes, also set them to checked in Interface Builder too). I've also read in another question with a similar problem that I should try overriding 'canBecomeFirstResponder' to return 'YES' and I've also done that too. But the problem persists, I can't click the button. I've not given any special properties, settings to the button, it's just a regular one. My other objects in the view (labels below, image view behind the button etc.) are working properly without problems. What could be possibly wrong here?
Thanks,
Can.
UPDATE: Here is a quick reproduction of the problem: https://dl.dropbox.com/u/79632924/Test.zip
Try to run and click the button.
Looking at the test project, I believe your problem in the way you create TestView, you do not specify the frame for it, so basically the parent view is 0 size, and the subviews you see from XIB extending out of the parent view and thus do not get anything in responder chain.
You should either specify the frame when creating TestView, or adjust the frame after loading XIB file.
I have had this problem as well. The cause for me was that the UIButton superview frame was of height 0, so I believe that even though a touch was happening, it was not being passed down to the button.
After making sure that the button's superview took a larger rectangle as a frame the button actions worked.
The root cause for this problem on my side was a faulty auto layout implementation (I forgot to set the height constraint for the button's superview).
I've found the solution. I was initializing my custom view as:
MyView *view = [[MyView alloc] init];
I've initialized it instead with a frame of my view's size, and it started responding to events:
CGRect rect = CGRectMake(0,0,width,height);
MyView *view = [[MyView alloc] initWithFrame:rect];
Storyboard Solution
Just for anyone wanting a solution to this when using storyboards and constraints.
Add a constraint between the superview (containing the button) and the UIButton with an equal heights constraint.
In my case, I had selected embed UIButton in a UIView with no inset on the storyboard. Adding the additional height constraint between the UIButton and the superview allowed the UIButton to respond to touches.
You can confirm the issue by starting the View Debugger and visually confirm that the superview of the UIButton is not selectable.
(Xcode 11, *- Should also work in earlier versions)

UITableViewCell Delete button screws up textLabel when using line break in text

I have a UITableViewCell, when swipe to bring up the Delete button it screws up the textLabel because I am using a line break in text.
Before:
In delete mode:
This is frustrating because I just want the delete button to go over my text, rather than trying to animate it out of the way which screws it up.
Why does this happen? Because I use a line break in my string?
How can I prevent this from happening?
Why does this happen? Because I use a line break in my string?
It happends because you've added the label to the contentView of the cell (which is good). When the delete button appears the contentView will be automatically resized and the UITableViewCell's textLabel will resize as well because it's autoresizingMask is set to UIViewAutoresizingFlexibleWidth. Unfortunately we cannot override the autoresizingMask of the default textLabel.
How can I prevent this from happening?
You'll have to build a custom cell yourself. Subclass UITableViewCell with a custom UILabel as a property and set it's autoresizingMask to UIViewAutoresizingNone.
//create and set your frame to whatever you want.
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(20, 20, 110, 20)];
//set autoresizing
[label setAutoresizingMask:UIViewAutoresizingNone];
//add to view
[[self contentView] addSubview:label];
//set property to acces later
[self myLabel:label];
//release (if you aren't using ARC)
[myLabel release];
add some sample text to test it later on
[[cell myLabel] setText:#"MAX: 72.92 MPH Will fit!"];
If you're using interfacebuilder to create your view/cells make sure the autoresizing mask arrow's are grayed out.
You should be able to access the UITableViewCell's textLabel.Frame property. Subclass UITableViewCell and set this in [UITableViewCell didTransitionToState:(UITableViewCellStateMask)state]

UITextField -- Adding UIView for leftView - Can't get Focus

The UITextFields in my app have placeholder text defined (in Interface Builder), and I cannot cause these fields to acquire focus (i.e. show the keyboard and allow editing) when I tap on the area occupied by the placeholder text. If I tap on the textfields in an area just outside the that of placeholder text (though still within the bounds of the textfiled itself), it acts as normal (i.e. the keyboard pops up and I can edit the content of the textfield). How can I fix this?
Thanks.
EDIT 1
Ok, I think I've got it. I'm also setting a blank view to the "leftView" property of these UITextFields. If I remove this, you can touch the UITextFields in the area of the placeholder text and it reacts as expected; I need this view for the leftView though. If you change the background color of this spacer view to red, you can see that it doesn't get in the way at all, so I don't know what's going wrong.
Why does this code cause this problem?
Thanks.
+(UIView*)getTextFieldLeftSpacerViewWithBackgroundColor:(UIColor*)backgroundColor andHeight:(CGFloat)height
{
UIView *leftWrapper = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 8.0f, height)];
leftWrapper.autoresizingMask = UIViewAutoresizingNone;
[leftWrapper setOpaque:YES];
if(backgroundColor){leftWrapper.backgroundColor = backgroundColor;}
else{leftWrapper.backgroundColor = [UIColor clearColor];}
return [leftWrapper autorelease];
}
+(void)setTextFieldLeftSpacerForTextFieled:(UITextField*)textField
{
if(textField)
{
UIView *spacer = [MYViewController getTextFieldLeftSpacerViewWithBackgroundColor:nil andHeight:textField.bounds.size.height];
textField.leftView = spacer;
textField.leftViewMode = UITextFieldViewModeAlways;
}
}
Just ran into the same problem and didn't want to subclass, just had to use :
leftWrapper.userInteractionEnabled = NO;
I abandoned this approach. Instead of using an invisible view to offset the text, I opted to subclass UITextField and provide offset CGRects for the bounds of the text within theUITextField. The following SO post was very helpful:
Indent the text in a UITextField

How do you determine the size/frame of a custom UINavigationItem.titleView?

After creating a custom view and assigning it to the navigationItem.titleView property it is displayed like this
with the custom view filling the space between the two buttons. Therefore, the custom view is not centered on the navigation bar. How do I determine the frame of the view in the .titleView property? I want to center some text in the navigation bar, say under the time stamp.
If you really want to get titleView's frame (in your top-level view's coordinate space), you can do this:
[self.navBar layoutIfNeeded];
CGRect titleViewFrameInTopLevelViewSpace = [self.navigationItem.titleView
convertRect:self.navigationItem.titleView.bounds
toView:self.view];
You need to do layoutIfNeeded if you have just assigned titleView, because by default the navigation bar won't lay out its subviews until the next pass through the run loop.
That said, the titleView will be centered automatically, if it fits. I think you are setting the frame (or bounds) of your custom view too large. I tested this two ways:
I set up the titleView directly in the XIB. I simply dragged a View from the Object library onto the center of the navigation bar:
It sized the view to 128x33 automatically. The resize handles let me adjust the size. It stays centered until it overlaps the Categorize button. Then it shifts left.
I set the titleView property in viewDidLoad:
- (void)viewDidLoad
{
[super viewDidLoad];
UIView *customView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 50, 33)];
customView.backgroundColor = [UIColor greenColor];
self.navItem.titleView = customView;
}
The result looks like this:
You could get the width of the leftBarButtonItem and the rightBarButtonItem after you've set them, and then use that to determine how to centre within the view you supply to titleView. That might do what you want?