/* Copyright 2018-present the Material Components for iOS authors. All Rights Reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #import "MaterialTextFields.h" @interface TextFieldCustomFontExample : UIViewController @property(nonatomic) MDCTextInputControllerOutlined *systemFontController; @property(nonatomic) MDCTextInputControllerOutlined *systemFontDynamicController; @property(nonatomic) MDCTextInputControllerOutlined *customFontController; @property(nonatomic) MDCTextInputControllerOutlined *customFontDynamicController; @property(nonatomic) MDCTextInputControllerOutlinedTextArea *multilineController; @property(nonatomic) MDCTextInputControllerOutlinedTextArea *multilineDynamicController; @property(nonatomic) MDCTextInputControllerOutlinedTextArea *multilineCustomFontDynamicController; @property(nonatomic) UIFont *normalTextFont; @property(nonatomic) UIScrollView *scrollView; @end @implementation TextFieldCustomFontExample - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; [self registerKeyboardNotifications]; [self setupScrollView]; // Create a System Font TextField. MDCTextField *systemFontTextField = [self setupSystemFontTextField]; // Create a System Font Dynamic TextField. MDCTextField *systemFontDynamicTextField = [self setupSystemFontDynamicTextField]; // Create a Custom Font TextField. MDCTextField *customFontTextField = [self setupCustomFontTextField];; // Create a Custom Font Dynamic TextField. MDCTextField *customFontDynamicTextField = [self setupCustomFontDynamicTextField];; // Create a System Multiline TextField. MDCMultilineTextField *multilineTextField = [self setupSystemMultilineTextField]; // Create a System Multiline Dynamic TextField. MDCMultilineTextField *multilineDynamicTextField = [self setupSystemMultilineDynamicTextField]; // Create a Custom Multiline Dyamic TextField. MDCMultilineTextField *multilineCustomDynamicTextField = [self setupCustomMultilineDynamicTextField]; NSDictionary *views = @{ @"t1" : systemFontTextField, @"t2" : systemFontDynamicTextField, @"t3" : customFontTextField, @"t4" : customFontDynamicTextField, @"t5" : multilineTextField, @"t6" : multilineDynamicTextField, @"t7" : multilineCustomDynamicTextField }; NSMutableArray *constraints = [NSMutableArray arrayWithArray: [NSLayoutConstraint constraintsWithVisualFormat:@"V:[t1]-[t2]-[t3]-[t4]-[t5]-[t6]-[t7]" options:NSLayoutFormatAlignAllLeading | NSLayoutFormatAlignAllTrailing metrics:nil views:views]]; [constraints addObject:[NSLayoutConstraint constraintWithItem:systemFontTextField attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeadingMargin multiplier:1 constant:0]]; [constraints addObject:[NSLayoutConstraint constraintWithItem:systemFontTextField attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTrailingMargin multiplier:1 constant:0]]; #if defined(__IPHONE_11_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0) if (@available(iOS 11.0, *)) { [NSLayoutConstraint activateConstraints:@[ [NSLayoutConstraint constraintWithItem:systemFontTextField attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.scrollView.contentLayoutGuide attribute:NSLayoutAttributeTop multiplier:1 constant:20], [NSLayoutConstraint constraintWithItem:multilineCustomDynamicTextField attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.scrollView.contentLayoutGuide attribute:NSLayoutAttributeBottomMargin multiplier:1 constant:-20] ]]; } else { [NSLayoutConstraint activateConstraints:@[ [NSLayoutConstraint constraintWithItem:systemFontTextField attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.scrollView attribute:NSLayoutAttributeTop multiplier:1 constant:20], [NSLayoutConstraint constraintWithItem:multilineCustomDynamicTextField attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.scrollView attribute:NSLayoutAttributeBottomMargin multiplier:1 constant:-20] ]]; } #else [NSLayoutConstraint activateConstraints:@[ [NSLayoutConstraint constraintWithItem:systemFontTextField attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.scrollView attribute:NSLayoutAttributeTop multiplier:1 constant:20], [NSLayoutConstraint constraintWithItem:systemFontTextField attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.scrollView attribute:NSLayoutAttributeBottomMargin multiplier:1 constant:-20] ]]; #endif [NSLayoutConstraint activateConstraints:constraints]; } - (void)setupScrollView { self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectZero]; self.scrollView.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:self.scrollView]; NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[scrollView]|" options:0 metrics:nil views:@{@"scrollView" : self.scrollView}]; [NSLayoutConstraint activateConstraints:constraints]; constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[scrollView]|" options:0 metrics:nil views:@{@"scrollView" : self.scrollView}]; [NSLayoutConstraint activateConstraints:constraints]; UIEdgeInsets margins = UIEdgeInsetsMake(0, 16, 0, 16); self.scrollView.layoutMargins = margins; UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapDidTouch:)]; [self.scrollView addGestureRecognizer:tapGestureRecognizer]; } - (MDCTextField *)setupSystemFontTextField { MDCTextField *systemFontTextField = [[MDCTextField alloc] init]; self.normalTextFont = systemFontTextField.font; systemFontTextField.translatesAutoresizingMaskIntoConstraints = NO; [self.scrollView addSubview:systemFontTextField]; systemFontTextField.delegate = self; systemFontTextField.clearButtonMode = UITextFieldViewModeUnlessEditing; systemFontTextField.backgroundColor = [UIColor whiteColor]; self.systemFontController = [[MDCTextInputControllerOutlined alloc] initWithTextInput:systemFontTextField]; self.systemFontController.placeholderText = @"System Font"; self.systemFontController.mdc_adjustsFontForContentSizeCategory = NO; return systemFontTextField; } - (MDCTextField *)setupSystemFontDynamicTextField { MDCTextField *systemFontDynamicTextField = [[MDCTextField alloc] init]; systemFontDynamicTextField.translatesAutoresizingMaskIntoConstraints = NO; [self.scrollView addSubview:systemFontDynamicTextField]; systemFontDynamicTextField.delegate = self; systemFontDynamicTextField.clearButtonMode = UITextFieldViewModeUnlessEditing; systemFontDynamicTextField.backgroundColor = [UIColor whiteColor]; self.systemFontDynamicController = [[MDCTextInputControllerOutlined alloc] initWithTextInput:systemFontDynamicTextField]; self.systemFontDynamicController.placeholderText = @"System Font - Dynamic"; self.systemFontDynamicController.mdc_adjustsFontForContentSizeCategory = YES; return systemFontDynamicTextField; } - (MDCTextField *)setupCustomFontTextField { MDCTextField *customFontTextField = [[MDCTextField alloc] init]; customFontTextField.translatesAutoresizingMaskIntoConstraints = NO; [self.scrollView addSubview:customFontTextField]; customFontTextField.delegate = self; customFontTextField.clearButtonMode = UITextFieldViewModeUnlessEditing; customFontTextField.backgroundColor = [UIColor whiteColor]; self.customFontController = [[MDCTextInputControllerOutlined alloc] initWithTextInput:customFontTextField]; self.customFontController.placeholderText = @"Custom Font"; self.customFontController.mdc_adjustsFontForContentSizeCategory = NO; self.customFontController.leadingUnderlineLabelFont = [UIFont fontWithName:@"AmericanTypewriter" size:12]; self.customFontController.trailingUnderlineLabelFont = [UIFont fontWithName:@"Chalkduster" size:12]; self.customFontController.inlinePlaceholderFont = [UIFont fontWithName:@"AmericanTypewriter" size:12]; self.customFontController.textInputFont = [UIFont fontWithName:@"Chalkduster" size:16]; return customFontTextField; } - (MDCTextField *)setupCustomFontDynamicTextField { MDCTextField *customFontDynamicTextField = [[MDCTextField alloc] init]; customFontDynamicTextField.translatesAutoresizingMaskIntoConstraints = NO; customFontDynamicTextField.delegate = self; customFontDynamicTextField.clearButtonMode = UITextFieldViewModeUnlessEditing; customFontDynamicTextField.backgroundColor = [UIColor whiteColor]; self.customFontDynamicController = [[MDCTextInputControllerOutlined alloc] initWithTextInput:customFontDynamicTextField]; self.customFontDynamicController.placeholderText = @"Custom Font - Dynamic"; self.customFontDynamicController.helperText = @"Helper"; self.customFontDynamicController.leadingUnderlineLabelFont = [UIFont fontWithName:@"Zapfino" size:12]; self.customFontDynamicController.trailingUnderlineLabelFont = [UIFont fontWithName:@"Chalkduster" size:12]; self.customFontDynamicController.inlinePlaceholderFont = [UIFont fontWithName:@"Zapfino" size:12]; self.customFontDynamicController.textInputFont = [UIFont fontWithName:@"Zapfino" size:16]; self.customFontDynamicController.mdc_adjustsFontForContentSizeCategory = YES; [self.scrollView addSubview:customFontDynamicTextField]; return customFontDynamicTextField; } - (MDCMultilineTextField *)setupSystemMultilineTextField { MDCMultilineTextField *multilineTextField = [[MDCMultilineTextField alloc] init]; multilineTextField.translatesAutoresizingMaskIntoConstraints = NO; [self.scrollView addSubview:multilineTextField]; multilineTextField.textView.delegate = self; self.multilineController = [[MDCTextInputControllerOutlinedTextArea alloc] initWithTextInput:multilineTextField]; self.multilineController.placeholderText = @"Multiline Text"; self.multilineController.mdc_adjustsFontForContentSizeCategory = NO; return multilineTextField; } - (MDCMultilineTextField *)setupSystemMultilineDynamicTextField { MDCMultilineTextField *multilineDynamicTextField = [[MDCMultilineTextField alloc] init]; multilineDynamicTextField.translatesAutoresizingMaskIntoConstraints = NO; [self.scrollView addSubview:multilineDynamicTextField]; multilineDynamicTextField.textView.delegate = self; self.multilineDynamicController = [[MDCTextInputControllerOutlinedTextArea alloc] initWithTextInput:multilineDynamicTextField]; self.multilineDynamicController.placeholderText = @"Multiline Dynamic Text"; self.multilineDynamicController.mdc_adjustsFontForContentSizeCategory = YES; return multilineDynamicTextField; } - (MDCMultilineTextField *)setupCustomMultilineDynamicTextField { MDCMultilineTextField *multilineCustomDynamicTextField = [[MDCMultilineTextField alloc] init]; multilineCustomDynamicTextField.translatesAutoresizingMaskIntoConstraints = NO; [self.scrollView addSubview:multilineCustomDynamicTextField]; multilineCustomDynamicTextField.textView.delegate = self; self.multilineCustomFontDynamicController = [[MDCTextInputControllerOutlinedTextArea alloc] initWithTextInput:multilineCustomDynamicTextField]; self.multilineCustomFontDynamicController.placeholderText = @"Multiline Custom Font Dynamic Text"; self.multilineCustomFontDynamicController.leadingUnderlineLabelFont = [UIFont fontWithName:@"AmericanTypewriter" size:12]; self.customFontDynamicController.trailingUnderlineLabelFont = [UIFont fontWithName:@"Chalkduster" size:12]; self.multilineCustomFontDynamicController.inlinePlaceholderFont = [UIFont fontWithName:@"Zapfino" size:12]; self.multilineCustomFontDynamicController.textInputFont = [UIFont fontWithName:@"AmericanTypewriter" size:16]; self.multilineCustomFontDynamicController.mdc_adjustsFontForContentSizeCategory = YES; return multilineCustomDynamicTextField; } #pragma mark - UITextFieldDelegate - (BOOL)textFieldShouldReturn:(UITextField *)textField { [textField resignFirstResponder]; return NO; } - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { NSString *finishedString = [textField.text stringByReplacingCharactersInRange:range withString:string]; if (textField == (UITextField *)self.systemFontController.textInput) { if ([finishedString rangeOfCharacterFromSet:[NSCharacterSet decimalDigitCharacterSet]].length && ![self.systemFontController.errorText isEqualToString:@"Error: You cannot enter numbers"]) { // The entered text contains numbers and we have not set an error [self.systemFontController setErrorText:@"You cannot enter numbers" errorAccessibilityValue:nil]; // Since we are doing manual layout, we need to react to the expansion of the input that will // come from setting an error. [self.view setNeedsLayout]; } else if (self.systemFontController.errorText != nil) { // There should be no error but error text is being shown. [self.systemFontController setErrorText:nil errorAccessibilityValue:nil]; // Since we are doing manual layout, we need to react to the contraction of the input that // will come from setting an error. [self.view setNeedsLayout]; } } if (textField == (UITextField *)self.customFontController.textInput) { if ([finishedString rangeOfCharacterFromSet:[[NSCharacterSet letterCharacterSet] invertedSet]] .length > 0) { [self.customFontController setErrorText:@"Error: City can only contain letters" errorAccessibilityValue:nil]; } else { [self.customFontController setErrorText:nil errorAccessibilityValue:nil]; } } return YES; } #pragma mark - UITextViewDelegate - (void)textViewDidChange:(UITextView *)textView { NSLog(@"%@", textView.text); } #pragma mark - Gesture Handling - (void)tapDidTouch:(UIGestureRecognizer *)sender { [self.view endEditing:YES]; } #pragma mark - Keyboard Handling - (void)registerKeyboardNotifications { NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter]; [defaultCenter addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [defaultCenter addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillChangeFrameNotification object:nil]; [defaultCenter addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; } - (void)keyboardWillShow:(NSNotification *)notif { CGRect keyboardFrame = [notif.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; self.scrollView.contentInset = UIEdgeInsetsMake(0, 0, CGRectGetHeight(keyboardFrame), 0); } - (void)keyboardWillHide:(NSNotification *)notif { self.scrollView.contentInset = UIEdgeInsetsZero; } #pragma mark - Phone Number Validation - (BOOL)isValidPhoneNumber:(NSString *)inputString partially:(BOOL)isPartialCheck { // In real life there would be much more robust validation that takes locale into account, checks // against invalid phone numbers (like those that begin with 0), and perhaps even auto-inserts the // hyphens so the user doesn't have to. if (inputString.length == 0) { return YES; } NSCharacterSet *characterSet = [NSCharacterSet characterSetWithCharactersInString:@"0123456789-"]; characterSet = [characterSet invertedSet]; BOOL isValid = ![inputString rangeOfCharacterFromSet:characterSet].length; if (!isPartialCheck) { isValid = isValid && inputString.length == 12; } else { isValid = isValid && inputString.length <= 12; } return isValid; } @end @implementation TextFieldCustomFontExample (CatalogByConvention) + (NSArray *)catalogBreadcrumbs { return @[ @"Text Field", @"Custom Fonts" ]; } + (BOOL)catalogIsPrimaryDemo { return NO; } + (BOOL)catalogIsPresentable { return NO; } @end