Search code examples
iosobjective-cuitextfieldautolayoutuinavigationitem

wrong Layout for replacing UiNavigationItem.Title with UITextField


i wont replace the UINavigationItem.title with UITextfield.

to make this i add in viewDidLoad the TextField

UITextField *textField = [[UITextField alloc]initWithFrame:CGRectMake(0, 0, 150, 30)];
textField.text = @"";
textField.placeholder = @"set title here";
textField.font = [UIFont fontWithName:@"Futura-Medium" size:19.0];
textField.textColor = [UIColor whiteColor];
textField.textAlignment = NSTextAlignmentCenter;
textField.autoresizingMask = UIViewAutoresizingFlexibleWidth;
textField.translatesAutoresizingMaskIntoConstraints = NO;
textField.delegate = self;

self.navigationItem.titleView = textField;

but I have problems during the execution of positioning and sizing of the TextField:

portraitlandscape

I wish that the TextField would behave like the NavigationItem.title

any idea?

thank's in advance

---this is my class---

#import "CustomCategoryViewController.h"

@interface CustomCategoryViewController ()<UITextFieldDelegate>

@end

@implementation CustomCategoryViewController

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.

  NSLog(@"%f",self.navigationController.navigationItem.titleView.frame.size.height);

UITextField *textField = [[UITextField alloc]initWithFrame:CGRectMake(0, 0, 150, 30)];
textField.text = @"";
textField.placeholder = @"set title here";
textField.font = [UIFont fontWithName:@"Futura-Medium" size:19.0];
textField.textColor = [UIColor whiteColor];
textField.textAlignment = NSTextAlignmentCenter;
textField.autoresizingMask = UIViewAutoresizingFlexibleWidth;
textField.translatesAutoresizingMaskIntoConstraints = NO;
textField.delegate = self;

self.navigationItem.titleView = textField;
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - TextField Delegate

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
{
    NSCharacterSet  *set = [NSCharacterSet newlineCharacterSet];

    if ([string rangeOfCharacterFromSet:[set invertedSet]].location == NSNotFound){

        [textField endEditing:YES];
    }

    return YES;
}

- (BOOL)textFieldShouldClear:(UITextField *)textField
{
    //self.commonName = @"";
    return YES;
}

- (void)textFieldDidEndEditing:(UITextField *)textField
{
    if (textField.text && ![textField.text isEqualToString:@""]) {
        CGRect rect = [textField textRectForBounds:textField.bounds];
        [textField setBounds:CGRectMake(0, 0, rect.size.width, rect.size.height)];
    }
    else{
        CGRect rect = [textField placeholderRectForBounds:textField.bounds];
        [textField setBounds:CGRectMake(0, 0, rect.size.width, rect.size.height)];
    }
}

#pragma mark - Keyboard

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self.view endEditing:YES];
}

- (IBAction)textFieldReturn:(id)sender
{
    [sender resignFirstResponder];
}

#pragma mark - Interface Orientation


- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return YES;
}

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];

    // Code here will execute before the rotation begins.
    // Equivalent to placing it in the deprecated method -[willRotateToInterfaceOrientation:duration:]

    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {

        // Place code here to perform animations during the rotation. You can leave this block empty if not necessary.
        dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
            //Background Thread
            dispatch_async(dispatch_get_main_queue(), ^(void){

            });
        });

    } completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {

        // Code here will execute after the rotation has finished.
        // Equivalent to placing it in the deprecated method -[didRotateFromInterfaceOrientation:]

    }];
}
/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

Solution

  • Currently your textField is taking 150 width and its content stays in center so as result you see you text is floating to one side when you have long barButton.

    You will need to set textField bounds to fit the text OR placeHolder after every time you edit textField like

    - (void)textFieldDidEndEditing:(UITextField *)textField
    {
        if (textField.text && ![textField.text isEqualToString:@""]) {
             CGRect textRect = [textField.text boundingRectWithSize:CGSizeMake(300,30)
                                    options:NSStringDrawingUsesLineFragmentOrigin
                                    attributes:@{NSFontAttributeName:textField.font}
                                    context:nil];
    
             [textField setBounds:CGRectMake(0, 0, textRect.size.width, textRect.size.height)];
        }
        else{
             CGRect textRect = [textField.placeholder boundingRectWithSize:CGSizeMake(300,30)
                                    options:NSStringDrawingUsesLineFragmentOrigin
                                    attributes:@{NSFontAttributeName:textField.font}
                                    context:nil];
    
             [textField setBounds:CGRectMake(0, 0, textRect.size.width, textRect.size.height)];
        }
    }
    

    After this your textField would be exact sized to its content and it would stay in center of navigationBar.