调整inputAccessoryView中的文本字段的大小

我一直在试图让UITextView整个星期resize。 我不明白应该怎么做,所以我决定把所有相关的代码都包括在内。

我有这个对话视图:

对话视图

这个conversationview是一个带UITableViewUIViewController (使用约束)。 我有一个自定义的UIView子类ConversationToolbar设置为inputAccessoryView (包含它的UIViewController可以成为第一响应者,所以视图始终可见),包含2个子视图。 一个用于UITextView和左右button,另一个用于表情符号。 表情符号仅在点击左键时显示:

情感观点

当select一个时,它显示在一个浮动标签上:

浮动的情绪

当使用多行时,我现在无法调整这个UITextView大小。 我试图自己计算所有的框架,但那似乎与我的约束以某种奇怪的方式相冲突。 几乎总是UITextView太小,或者只有当我按下另一个键来更新视图时才resize。 或者UITextView在键盘上变得更大,或者当键盘被解散时它滑出视图。

我已经从我的代码中删除了所有resize的function,我想知道我需要做什么来resize。

在我的ConversationViewController

 var toolbar: ConversationToolbar! override var inputAccessoryView: UIView! { get { if toolbar == nil { toolbar = NSBundle.mainBundle().loadNibNamed("ConversationToolbar", owner: nil, options: nil).last! as ConversationToolbar toolbar.frame.size = CGSize(width: UIScreen.mainScreen().bounds.size.width, height: 80) toolbar.delegate = self toolbar.setDraft(conversation.draft) } return toolbar } } 

ConversationToolbar.xib是:

 <?xml version="1.0" encoding="UTF-8" standalone="no"?> <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="6254" systemVersion="14D87p" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES"> <dependencies> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="6247"/> </dependencies> <objects> <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/> <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> <view contentMode="scaleToFill" id="iN0-l3-epB" customClass="ConversationToolbar" customModule="Heaven_Help" customModuleProvider="target"> <rect key="frame" x="0.0" y="0.0" width="600" height="600"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <subviews> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="s5O-PN-dtz"> <rect key="frame" x="0.0" y="554" width="600" height="46"/> <subviews> <button opaque="NO" contentMode="scaleToFill" horizontalCompressionResistancePriority="749" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="pbw-hg-sNn"> <rect key="frame" x="0.0" y="0.0" width="36" height="46"/> <inset key="contentEdgeInsets" minX="8" minY="0.0" maxX="8" maxY="0.0"/> <state key="normal" title="😶"> <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> </state> <connections> <action selector="emoPress:" destination="iN0-l3-epB" eventType="touchUpInside" id="hLw-rH-Hym"/> </connections> </button> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Vid-Ac-jz3"> <rect key="frame" x="548" y="0.0" width="52" height="46"/> <inset key="contentEdgeInsets" minX="8" minY="0.0" maxX="8" maxY="0.0"/> <state key="normal" title="Send"> <color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/> </state> <connections> <action selector="sendPress:" destination="iN0-l3-epB" eventType="touchUpInside" id="rzU-Vk-nJa"/> </connections> </button> <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Czv-f6-jOP"> <rect key="frame" x="36" y="8" width="512" height="30"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <fontDescription key="fontDescription" type="system" pointSize="14"/> <textInputTraits key="textInputTraits" autocapitalizationType="sentences"/> </textView> </subviews> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> <constraints> <constraint firstAttribute="height" constant="46" id="D1D-QM-5n2"/> <constraint firstAttribute="trailing" secondItem="Vid-Ac-jz3" secondAttribute="trailing" id="H9Y-xT-aqe"/> <constraint firstAttribute="centerY" secondItem="pbw-hg-sNn" secondAttribute="centerY" id="IYf-5R-S97"/> <constraint firstItem="Czv-f6-jOP" firstAttribute="leading" secondItem="pbw-hg-sNn" secondAttribute="trailing" id="LpH-ir-M9U"/> <constraint firstAttribute="centerY" secondItem="Vid-Ac-jz3" secondAttribute="centerY" id="NQ1-m1-9rk"/> <constraint firstAttribute="bottom" secondItem="Vid-Ac-jz3" secondAttribute="bottom" id="UUt-1r-emN"/> <constraint firstItem="Czv-f6-jOP" firstAttribute="top" secondItem="s5O-PN-dtz" secondAttribute="top" constant="8" id="VWB-7N-LrK"/> <constraint firstAttribute="bottom" secondItem="Czv-f6-jOP" secondAttribute="bottom" constant="8" id="WTi-8a-kaM"/> <constraint firstItem="pbw-hg-sNn" firstAttribute="leading" secondItem="s5O-PN-dtz" secondAttribute="leading" id="a4Q-W4-ROh"/> <constraint firstAttribute="bottom" secondItem="pbw-hg-sNn" secondAttribute="bottom" id="hGG-Xe-FZZ"/> <constraint firstItem="Vid-Ac-jz3" firstAttribute="leading" secondItem="Czv-f6-jOP" secondAttribute="trailing" id="jc6-18-MYq"/> </constraints> </view> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="rh6-cD-U1e"> <rect key="frame" x="0.0" y="508" width="600" height="46"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/> </view> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6zz-GF-eHs"> <rect key="frame" x="279" y="525" width="42" height="21"/> <fontDescription key="fontDescription" type="system" pointSize="17"/> <color key="textColor" cocoaTouchSystemColor="darkTextColor"/> <nil key="highlightedColor"/> </label> </subviews> <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/> <constraints> <constraint firstAttribute="centerX" secondItem="6zz-GF-eHs" secondAttribute="centerX" id="3at-fx-ZCR"/> <constraint firstAttribute="bottom" secondItem="s5O-PN-dtz" secondAttribute="bottom" id="3r5-GG-6Eo"/> <constraint firstItem="s5O-PN-dtz" firstAttribute="height" secondItem="rh6-cD-U1e" secondAttribute="height" id="MBP-k2-Qre"/> <constraint firstItem="s5O-PN-dtz" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="PLK-DE-38r"/> <constraint firstItem="s5O-PN-dtz" firstAttribute="top" secondItem="6zz-GF-eHs" secondAttribute="bottom" constant="8" symbolic="YES" id="PRr-qQ-oyf"/> <constraint firstAttribute="trailing" secondItem="s5O-PN-dtz" secondAttribute="trailing" id="PqA-VB-NxV"/> <constraint firstItem="s5O-PN-dtz" firstAttribute="top" secondItem="rh6-cD-U1e" secondAttribute="bottom" id="ZxJ-8p-Mjq"/> <constraint firstItem="rh6-cD-U1e" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="lsS-5I-Saq"/> <constraint firstAttribute="trailing" secondItem="rh6-cD-U1e" secondAttribute="trailing" id="yRP-hS-dpr"/> </constraints> <connections> <outlet property="emoButton" destination="pbw-hg-sNn" id="VJx-J0-hBJ"/> <outlet property="emoLabel" destination="6zz-GF-eHs" id="pUW-yD-pIq"/> <outlet property="emoView" destination="rh6-cD-U1e" id="0YV-Wx-clp"/> <outlet property="sendButton" destination="Vid-Ac-jz3" id="6FV-Q2-ufA"/> <outlet property="textSuperView" destination="s5O-PN-dtz" id="BIT-bH-p4M"/> <outlet property="textView" destination="Czv-f6-jOP" id="syf-v4-LLy"/> </connections> </view> </objects> </document> 

最后我的ConversationToolbar.swift

 import Foundation class ConversationToolbar: UIView, UITextViewDelegate { @IBOutlet weak var textView: UITextView! @IBOutlet weak var emoView: UIView! @IBOutlet weak var sendButton: UIButton! @IBOutlet weak var textSuperView: UIView! @IBOutlet weak var emoButton: UIButton! @IBOutlet weak var emoLabel: UILabel! var delegate: ConversationToolbarDelegate! var emobuttons: [String: UIButton]! var emoSelected: String? var clickableSend: Bool { get { return ((delegate?.hasEnoughCredits() ?? false) && !(textView?.text?.isEmpty ?? true)) ?? false } } override func awakeFromNib() { textView.delegate = self sendButton.enabled = clickableSend self.autoresizingMask = .FlexibleHeight // Make textView pretty textView.backgroundColor = UIColor.whiteColor() // (white: 250/255, alpha: 1) textView.font = UIFont.systemFontOfSize(17) textView.layer.borderColor = UIColor(red: 200/255, green: 200/255, blue: 205/255, alpha:1).CGColor textView.layer.borderWidth = 0.5 textView.layer.cornerRadius = 5 textView.scrollsToTop = false textView.textContainerInset = UIEdgeInsetsMake(4, 3, 3, 3) textView.autoresizingMask = .FlexibleHeight // Add a nice border to the view textSuperView.layer.borderColor = UIColor(red: 200/255, green: 200/255, blue: 205/255, alpha:1).CGColor textSuperView.layer.borderWidth = 0.5 textSuperView.backgroundColor = UIColor(white: 235/255, alpha: 1) textSuperView.autoresizingMask = .FlexibleHeight // Prettify emoView emoView.layer.borderColor = UIColor(red: 200/255, green: 200/255, blue: 205/255, alpha:1).CGColor emoView.layer.borderWidth = 0.5 emoView.backgroundColor = UIColor(white: 235/255, alpha: 1) // Emobar setup emobuttons = StaticData.getEmoButtons() let unusedSpace = UIScreen.mainScreen().bounds.width - emobuttons.sum { button in return button.intrinsicContentSize().width } let spaceBetweenButtons = Int(unusedSpace) / (emobuttons.count + 1) var visualLayout = "H:|" for button in emobuttons { button.1.setTranslatesAutoresizingMaskIntoConstraints(false) visualLayout += "-(space)-[\(button.0)]" emoView.addSubview(button.1) button.1.addTarget(self, action: "emoChosen:", forControlEvents: .TouchUpInside) } emoView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("\(visualLayout)-(space)-|", options: .AlignAllCenterY, metrics: ["space":spaceBetweenButtons], views: emobuttons)) emoView.addConstraint(NSLayoutConstraint(item: emoView, attribute: .CenterY, relatedBy: .Equal, toItem: emobuttons.values.array.first!, attribute: .CenterY, multiplier: 1, constant: 0)) // Prettify toolbar itself self.backgroundColor = UIColor.clearColor() // start hidden emoView.hidden = true emoLabel.hidden = emoSelected == nil } @IBAction func emoPress(sender: UIButton) { emoView.hidden = !emoView.hidden updateEmoLabel() if !emoView.hidden { emoLabel.hidden = true } } @IBAction func sendPress(sender: UIButton) { delegate.sendMessage(textView.text, feeling: emoSelected) textView.text = "" emoSelected = nil sendButton.enabled = false textViewDidChange(textView) updateEmoLabel() } func emoChosen(sender: UIButton) { emoView.hidden = true emoSelected = sender.titleLabel?.text == "🚫" ? nil : sender.titleLabel?.text updateEmoLabel() } func setDraft(draft: String) { textView.text = draft } func updateEmoLabel() { emoLabel.text = emoSelected emoLabel.hidden = emoSelected == nil } /// MARK: UITextFieldDelegate func textViewDidChange(textView: UITextView) { sendButton.enabled = clickableSend } } protocol ConversationToolbarDelegate { func sendMessage(text: String, feeling: String?) func hasEnoughCredits() -> Bool } 

我用AutoLayout解决了这个问题。 我已经添加了一个新的约束,定义我的UITextField的高度,我设置该约束的constanttextView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool

 func textView(textView: UITextView, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool { let oldHeight = textView.frame.height let newText = (textView.text as NSString).stringByReplacingCharactersInRange(range, withString: text) let newSize = (newText as NSString).boundingRectWithSize(CGSize(width: textView.frame.width - textView.textContainerInset.right - textView.textContainerInset.left - 10, height: CGFloat.max), options: .UsesLineFragmentOrigin, attributes: [NSFontAttributeName: textView.font], context: nil) let heightChange = newSize.height + textView.textContainerInset.top + textView.textContainerInset.bottom + 2.719 - oldHeight textFieldHeightLayoutConstraint.constant += heightChange return true } 

我遇到的问题是我设置AutoLayoutUIView.frame到不同的设置,导致他们的战斗。

我是一个白痴。

我很久以前解决了调整inputAccessoryView这个问题,但是直到今天还没有解决适当的UITextView调整iOS8的问题。 这是我的示例应用程序 – github

它使用框架的iOS7resize( UITextEffectsWindow手动布局,并在inputAccessoryView的创build约束意味着创build自动布局引擎,这导致自动布局引擎在inf / nan帧奇怪的转换后失败)和iOS8resize的约束。 无论如何, inputAccessoryView的视图布局永远不会正确完成,所以我们必须执行帧计算。

例1例题