2014-07-15 13 views
5

Ho qualche problema con il mio input personalizzato per UITextFields. A seconda del testo che l'utente deve inserire in un UITextField, inputView visualizza solo le lettere necessarie. Ciò significa che per i testi brevi è sufficiente un inputView con una sola riga di lettere, mentre i testi più lunghi possono richiedere 2 o anche 3 righe in modo che l'altezza di inputView sia variabile.Input personalizzato Visualizzazione con altezza dinamica in iOS 8

Poiché mi aspettavo prestazioni migliori, esiste solo un'istanza di inputView utilizzata da ogni campo di testo. In questo modo la creazione deve avvenire solo una volta e ha reso l'accesso diretto a volte necessario a inputView più semplice. InputView è impostato su - (BOOL)textFieldShouldBeginEditing:(UITextField *)textField, imposta la sua altezza richiesta e verrà mostrato.

Ciò funziona perfettamente, ma non su iOS8. C'è qualche vista di sistema che contiene l'inputView non aggiornerà il suo frame in modo che corrisponda ai limiti di inputView quando vengono modificati (la prima volta funziona).

So che può essere risolto utilizzando un'istanza del mio inputView per textField. Ma sto chiedendo se esiste un modo consigliato/migliore per regolare la cornice o segnalare la sua modifica alla vista contenente. Forse è un bug iOS8 che potrebbe essere risolto fino al rilascio?

Ecco qualche esempio di codice per riprodurre il problema:

CustomInputView

@implementation CustomInputView 

+ (CustomInputView*)sharedInputView{ 
    static CustomInputView *sharedInstance; 
    static dispatch_once_t onceToken; 
    dispatch_once(&onceToken, ^{ 
     sharedInstance = [[CustomInputView alloc] init]; 
    }); 
    return sharedInstance; 
} 

- (id)init 
{ 
    self = [super init]; 
    if (self) { 
     self.backgroundColor = [UIColor greenColor]; 
    } 
    return self; 
} 

- (void)setupForTextField:(UITextField*)textField{ 
    CGFloat height; 

    if(textField.tag == 1){ 
     height = 100; 
    }else height = 50; 

    self.frame = CGRectMake(0, 0, 320, height); 
} 
@end 

codice TestViewController

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    UITextField *tf = [[UITextField alloc] initWithFrame:CGRectMake(15, 50, 290, 30)]; 
    tf.text = @"bigKeyboard"; 
    tf.inputView = [CustomInputView sharedInputView]; 
    tf.layer.borderWidth = 1; 
    tf.layer.borderColor = [UIColor lightGrayColor].CGColor; 
    tf.delegate = self; 
    tf.tag = 1; 
    [self.view addSubview:tf]; 

    tf = [[UITextField alloc] initWithFrame:CGRectMake(15, 100, 290, 30)]; 
    tf.text = @"smallKeyboard"; 
    tf.inputView = [CustomInputView sharedInputView]; 
    tf.layer.borderWidth = 1; 
    tf.layer.borderColor = [UIColor lightGrayColor].CGColor; 
    tf.delegate = self; 
    tf.tag = 2; 
    [self.view addSubview:tf]; 

    UIButton *button = [UIButton buttonWithType:UIButtonTypeSystem]; 
    [button setTitle:@"dismissKeyboard" forState:UIControlStateNormal]; 
    [button addTarget:self action:@selector(endEditing) forControlEvents:UIControlEventTouchUpInside]; 
    button.frame = CGRectMake(15, 150, 290, 30); 
    [self.view addSubview:button]; 
} 

- (void)endEditing{ 
    [self.view endEditing:YES]; 
} 

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{ 
    [[CustomInputView sharedInputView] setupForTextField:textField]; 
    return YES; 
} 
+0

Hai trovato qualche soluzione per ridimensionare inputView? Ho bisogno di un'altezza inputView fissa per iPad. –

+0

Se hai bisogno di un'altezza fissa, dovrebbe funzionare - l'inputView rimarrà all'altezza specificata al momento della creazione. Se è necessario modificare l'altezza in un secondo momento, non sono ancora a conoscenza di una soluzione. Ho preso la soluzione alternativa di creare un inputView per textField che era ok per il mio caso ... – robert

risposta

12

ho avuto problemi simili con il dimensionamento di un tastiera personalizzata da iOS 8 a iOS 10. Credo che la soluzione corretta sia avere la visualizzazione di input che fornisca il valore corretto intrinsicContentSize e modificare (e invalidare!) Quel valore quando si desidera cambiare t ha l'altezza della vista Esempio di codice:

class CustomInputView: UIInputView { 
    var intrinsicHeight: CGFloat = 200 { 
     didSet { 
      self.invalidateIntrinsicContentSize() 
     } 
    } 

    init() { 
     super.init(frame: CGRect(), inputViewStyle: .keyboard) 
     self.translatesAutoresizingMaskIntoConstraints = false 
    } 

    required init?(coder: NSCoder) { 
     super.init(coder: coder) 
     self.translatesAutoresizingMaskIntoConstraints = false 
    } 

    override var intrinsicContentSize: CGSize { 
     return CGSize(width: UIViewNoIntrinsicMetric, height: self.intrinsicHeight) 
    } 
} 

class ViewController: UIViewController { 
    @IBOutlet weak var textView: UITextView! 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     textView.becomeFirstResponder() 

     let inputView = CustomInputView() 
     // To make the view's size more clear. 
     inputView.backgroundColor = UIColor(red: 0.5, green: 1, blue: 0.5, alpha: 1) 
     textView.inputView = inputView 

     // To demonstrate a change to the view's intrinsic height. 
     DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + .seconds(2)) { 
      inputView.intrinsicHeight = 400 
     } 
    } 
} 

Vedere anche https://stackoverflow.com/a/40359382/153354.

Problemi correlati