Resize a UITextField while typing (by using Autolayout)

后端 未结 9 1753
梦如初夏
梦如初夏 2020-12-04 13:05

I have a UITableViewCell which has two UITextFields (without borders). The following constraints are used to set up the horizontal layout.

@\"|-10-[leftTextFi

9条回答
  •  一整个雨季
    2020-12-04 13:29

    For some reason, calling invalidateIntrinsicContentSize wasn't working for me either, but I also ran into issues with the other solutions due to the margins and editing controls.

    This solution isn't always needed; if invalidateIntrinsicContentSize works, then all that needs to be done is to add a call to that when the text is changed, as in the other answers. If that isn't working, then here's a solution (adapted from here) I found which also works with a clear control:

    class AutoResizingUITextField: UITextField {
        var lastTextBeforeEditing: String?
    
        override init(frame: CGRect) {
            super.init(frame: frame)
            setupTextChangeNotification()
        }
    
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
            setupTextChangeNotification()
        }                
    
        func setupTextChangeNotification() {
            NotificationCenter.default.addObserver(
                forName: Notification.Name.UITextFieldTextDidChange,
                object: self,
                queue: OperationQueue.main) { (notification) in                   
                    self.invalidateIntrinsicContentSize()
            }
            NotificationCenter.default.addObserver(
                forName: Notification.Name.UITextFieldTextDidBeginEditing,
                object: self,
                queue: OperationQueue.main) { (notification) in
                    self.lastTextBeforeEditing = self.text
            }
        }                
    
        override var intrinsicContentSize: CGSize {
            var size = super.intrinsicContentSize
    
            if isEditing, let text = text, let lastTextBeforeEditing = lastTextBeforeEditing {
                let string = text as NSString
                let stringSize = string.size(attributes: typingAttributes)
                let origSize = (lastTextBeforeEditing as NSString).size(attributes: typingAttributes)
                size.width = size.width + (stringSize.width - origSize.width)
            }
    
            return size
        }
    
        deinit {
            NotificationCenter.default.removeObserver(self)
        }
    }
    

    If invalidateIntrinsicContentSize is working by itself, this will end up double-counting the change so that needs to be checked first.

提交回复
热议问题