2017-06-15 3 views
0

今質問があります。私は、textField、tableViewとラベルを持っています。 textFieldテキストが空の場合、tableViewは隠されています。しかし、ユーザーがtextFieldに何かを入力すると、tableViewのリストがViewに表示されます。 TableViewの位置は、textFieldとlabelの間です。この制約を更新するには?私はこれをしようとするが、それは私のためには動作しません。ありがとう。textFieldにテキストが入力されたときに制約を更新する方法

class ViewController: UIViewController, UITextFieldDelegate,UITableViewDelegate,UITableViewDataSource { 

var tableView: UITableView = UITableView() 
var textField: UITextField = UITextField() 
var label:UILabel = UILabel() 
var haveText:Bool = false 

var autoCompletePossibilities = ["Wand","Wizard","Test","1","12","123","1234","12345"] 
var autoComplete = [String]() 

var tableviewHeightConstraint:NSLayoutConstraint? 

override func loadView() { 
    super.loadView() 

    tableView.translatesAutoresizingMaskIntoConstraints = false 
    textField.translatesAutoresizingMaskIntoConstraints = false 
    label.translatesAutoresizingMaskIntoConstraints = false 

    loadContent() 

} 

override func viewWillLayoutSubviews() { 
    super.viewWillLayoutSubviews() 

    loadVFL() 
} 

override func viewDidLoad() { 
    super.viewDidLoad() 
    // Do any additional setup after loading the view, typically from a nib. 

    textField.delegate = self 
    tableView.delegate = self 
    tableView.dataSource = self 

    textField.backgroundColor = UIColor.lightGray 
    tableView.backgroundColor = UIColor.brown 
    label.backgroundColor = UIColor.cyan 
    label.text = "hello I'm beginner.Nice." 

} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

func DictionaryOfInstanceVariables(_ container:AnyObject, objects: String ...) -> [String:AnyObject] { 
    var views = [String:AnyObject]() 
    for objectName in objects { 
     guard let object = object_getIvar(container, class_getInstanceVariable(type(of: container), objectName)) else { 
      assertionFailure("\(objectName) is not an ivar of: \(container)"); 
      continue 
     } 
     views[objectName] = object as AnyObject? 
    } 
    return views 
} 

func loadContent() { 

    view.addSubview(textField) 
    view.addSubview(tableView) 
    view.addSubview(label) 
} 

func loadVFL() { 

    let views = DictionaryOfInstanceVariables(self, objects: 
     "textField" 
     ,"label" 
     ,"tableView" 
    ) 

    let metrics = ["padding":15] 

    self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[textField]|", options: [], metrics: metrics, views: views)) 
    self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[label]|", options: [], metrics: metrics, views: views)) 
    self.view.addConstraints (NSLayoutConstraint.constraints(withVisualFormat: "H:|[tableView]|", options: [], metrics: metrics, views: views)) 

    //declare tableview height constraints and init here 
    tableviewHeightConstraint = NSLayoutConstraint.init(item: view, 
                 attribute: .height, 
                 relatedBy: .equal, 
                 toItem: nil, 
                 attribute: .notAnAttribute, 
                 multiplier: 1, 
                 constant: 0) // init it with a 0 height 
    tableView.addConstraint(tableviewHeightConstraint!) // add the constraint to the tableView 
    self.view.addConstraints (NSLayoutConstraint.constraints(withVisualFormat: "V:|-50-[textField(60.0)][tableView][label(30.0)]", options: [], metrics: metrics, views: views)) 
} 

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

    let cell = UITableViewCell() 

    let index = indexPath.row as Int 

    cell.textLabel?.text = autoComplete[index] 
    cell.backgroundColor = UIColor.green 

    return cell 
} 

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 

    return autoComplete.count 
} 

func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool { 

    tableviewHeightConstraint?.constant = 160; // required height 
    UIView.animate(withDuration: 0.5) { // animate so it will be pretty 
     self.view.layoutIfNeeded() 
    } 
    return true 
} 

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { 

    let subString = (textField.text! as NSString).replacingCharacters(in: range, with: string) 

    searchAutocompleteEntriesWithSubString(subString: subString) 

    return true 
} 

func searchAutocompleteEntriesWithSubString(subString:String) 
{ 

    autoComplete.removeAll(keepingCapacity: false) 

    for key in autoCompletePossibilities { 

     let myString:NSString = key as NSString 

     let subStringRange:NSRange = myString.range(of: subString) 

     if subStringRange.location == 0 { 

      autoComplete.append(key) 
     } 
    } 

    tableView.reloadData() 
} 
} 

ログ印刷:

Probably at least one of the constraints in the following list is one you don't want. 
Try this: 
    (1) look at each constraint and try to figure out which you don't expect; 
    (2) find the code that added the unwanted constraint or constraints and fix it. 
(

"NSLayoutConstraint:0x60800009be40 V:[UITextField:0x7fc04db09e10]-(0)-[UITableView:0x7fc04e81e400] (active)", 

"NSLayoutConstraint:0x60800009bf30 UITableView:0x7fc04e81e400.height == 150 (active)", 

"NSLayoutConstraint:0x60800009d4c0 V:[UITableView:0x7fc04e81e400]-(0)-[UILabel:0x7fc04be057c0'hello I'm beginner.Nice.'] (active)", 

"NSLayoutConstraint:0x600000281360 V:[UITextField:0x7fc04db09e10]-(0)-[UILabel:0x7fc04be057c0'hello I'm beginner.Nice.'] (active)" 
) 

Will attempt to recover by breaking constraint 
NSLayoutConstraint:0x60800009d4c0 V:[UITableView:0x7fc04e81e400]-(0)-[UILabel:0x7fc04be057c0'hello I'm beginner.Nice.'] (active) 
Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger. 
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful. 

2017年6月16日更新や、新規クラッシュログ:

crash log here.

2017年6月16日最後に成功したコード:

class ViewController: UIViewController, UITextFieldDelegate,UITableViewDelegate,UITableViewDataSource { 

var tableView: UITableView = UITableView() 
var textField: UITextField = UITextField() 
var label:UILabel = UILabel() 
var haveText:Bool = false 

var autoCompletePossibilities = ["Wand","Wizard","Test","1","12","123","1234","12345"] 
var autoComplete = [String]() 

var tableviewHeightConstraint:NSLayoutConstraint? 

override func loadView() { 
    super.loadView() 

    tableView.translatesAutoresizingMaskIntoConstraints = false 
    textField.translatesAutoresizingMaskIntoConstraints = false 
    label.translatesAutoresizingMaskIntoConstraints = false 

    loadContent() 
    loadVFL() 
} 

override func viewDidLoad() { 
    super.viewDidLoad() 
    // Do any additional setup after loading the view, typically from a nib. 

    textField.delegate = self 
    tableView.delegate = self 
    tableView.dataSource = self 

    textField.backgroundColor = UIColor.lightGray 
    tableView.backgroundColor = UIColor.brown 
    label.backgroundColor = UIColor.cyan 
    label.text = "hello I'm beginner.Nice." 

} 

override func didReceiveMemoryWarning() { 
    super.didReceiveMemoryWarning() 
    // Dispose of any resources that can be recreated. 
} 

func DictionaryOfInstanceVariables(_ container:AnyObject, objects: String ...) -> [String:AnyObject] { 
    var views = [String:AnyObject]() 
    for objectName in objects { 
     guard let object = object_getIvar(container, class_getInstanceVariable(type(of: container), objectName)) else { 
      assertionFailure("\(objectName) is not an ivar of: \(container)"); 
      continue 
     } 
     views[objectName] = object as AnyObject? 
    } 
    return views 
} 

func loadContent() { 

    view.addSubview(textField) 
    view.addSubview(tableView) 
    view.addSubview(label) 
} 

func loadVFL() { 

    let views = DictionaryOfInstanceVariables(self, objects: 
     "textField" 
     ,"label" 
     ,"tableView" 
    ) 

    let metrics = ["padding":15] 

    tableviewHeightConstraint = NSLayoutConstraint.init(item: tableView, 
                 attribute: .height, 
                 relatedBy: .equal, 
                 toItem: nil, 
                 attribute: .height, 
                 multiplier: 1, 
                 constant: 0) // init it with a 0 height 
    tableView.addConstraint(tableviewHeightConstraint!) // add the constraint to the tableView 

    self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[textField]|", options: [], metrics: metrics, views: views)) 
    self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[label]|", options: [], metrics: metrics, views: views)) 
    self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[tableView]|", options: [], metrics: metrics, views: views)) 
    self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-50.0-[textField(60.0)][tableView][label(30.0)]", options: [], metrics: metrics, views: views)) 
} 

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 

    let cell = UITableViewCell() 

    let index = indexPath.row as Int 

    cell.textLabel?.text = autoComplete[index] 
    cell.backgroundColor = UIColor.green 

    return cell 
} 

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 

    return autoComplete.count 
} 

func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool { 

    super.updateViewConstraints() 

    tableView.removeConstraints(tableView.constraints) 
    tableviewHeightConstraint = NSLayoutConstraint(item: tableView, attribute: .height, relatedBy: .equal , toItem: nil, attribute: .height, multiplier: 1, constant: 160.0) 
    tableView.addConstraint(tableviewHeightConstraint!) // add the constraint to the tableView 

    UIView.animate(withDuration: 0.5) { // animate so it will be pretty 
     self.updateViewConstraints() 
     self.view.layoutIfNeeded() 
    } 
    return true 
} 

func textFieldShouldReturn(_ textField: UITextField) -> Bool { 

    super.updateViewConstraints() 

    textField.resignFirstResponder() 

    tableView.removeConstraints(tableView.constraints) 
    tableviewHeightConstraint = NSLayoutConstraint(item: tableView, attribute: .height, relatedBy: .equal , toItem: nil, attribute: .height, multiplier: 1, constant: 0.0) 
    tableView.addConstraint(tableviewHeightConstraint!) // add the constraint to the tableView 

    UIView.animate(withDuration: 0.5) { // animate so it will be pretty 
     self.updateViewConstraints() 
     self.view.layoutIfNeeded() 
    } 
    return true 
} 

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool { 

    let subString = (textField.text! as NSString).replacingCharacters(in: range, with: string) 

    searchAutocompleteEntriesWithSubString(subString: subString) 

    return true 
} 

func searchAutocompleteEntriesWithSubString(subString:String) 
{ 

    autoComplete.removeAll(keepingCapacity: false) 

    for key in autoCompletePossibilities { 

     let myString:NSString = key as NSString 

     let subStringRange:NSRange = myString.range(of: subString) 

     if subStringRange.location == 0 { 

      autoComplete.append(key) 
     } 
    } 

    tableView.reloadData() 
} 
} 

(IMAGE) Finally View like this.

+0

コンソールで何かエラーが発生しましたか? – Joshua

+0

私の質問を更新します。 – JimmyLee

+0

矛盾する制約。私はあなたが 'textFieldShouldBeginEditing'に制約を加えるべきではなく、' loadVFL'メソッドにロードするべきだと思います。代わりにUITableViewの高さを操作してください – Joshua

答えて

0

私のアプローチでは、すべての必要な制約がloadVFLにロードされます。あなたのtextShouldBeginEditing関数内で初期化した後

func loadVFL() { 

    let views = DictionaryOfInstanceVariables(self, objects: 
     "textField" 
     ,"tableView" 
     ,"label" 
    ) 

    let metrics = ["padding":15] 
    self.view.addConstraints (NSLayoutConstraint.constraints(withVisualFormat: "H:|[textField]|", options: [], metrics: metrics, views: views)) 
    self.view.addConstraints (NSLayoutConstraint.constraints(withVisualFormat: "H:|[tableView]|", options: [], metrics: metrics, views: views)) 
    self.view.addConstraints (NSLayoutConstraint.constraints(withVisualFormat: "H:|[label]|", options: [], metrics: metrics, views: views)) 

//declare tableview height constraints and init here 
    tableviewHeightConstraint = NSLayoutConstraint.init(item: tableView, 
               attribute: .height, 
               relatedBy: .equal, 
               toItem: nil, 
               attribute: .notAnAttribute, 
               multiplier: 1, 
               constant: 0) // init it with a 0 height 
    tableView.addConstraint(tableviewHeightConstraint) // add the constraint to the tableView 
    self.view.addConstraints (NSLayoutConstraint.constraints(withVisualFormat: "V:|-50-[textField(60.0)][tableView][label(30.0)]", options: [], metrics: metrics, views: views)) 
} 

は、あなたのテーブルビューの制約をアクティブにします

func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool { 
     tableviewHeightConstraint.constant = 160; // required height 
     UIView.animateWithDuration(0.5) { // animate so it will be pretty 
      self.view.layoutIfNeeded() 
     } 
     return true 
} 

あなたには、いくつかの機能でそれを非表示にする場合は、あなたが探して行われたときに呼び出します。定数を0に戻すだけで

私はそれがうまくいくと思います。試してみてください。

+0

あなたの答えをありがとう。 tableviewHeightConstraintはNSLayoutConstraintですか?私は "var tableviewHeightConstraint:NSLayoutConstraint?"そして、それはクラッシュします。私はクラッシュログに関する質問を更新します。 – JimmyLee

+0

クラッシュログとは何ですか? – Joshua

+0

私はすでに画像をアップロードしています。 – JimmyLee

関連する問題