2015-03-11 3 views
8

Я пытаюсь получить UITextView, чтобы изменить размер всей недели. Я не вижу, как это должно быть сделано, поэтому я решил включить практически весь соответствующий код.Изменение размера текстового поля в inputAccessoryView

У меня есть этот вид разговора:

Conversation View

Это conversationview является UIViewController с UITableView внутри (с помощью ограничений). У меня есть пользовательский UIView подкласс ConversationToolbar, установленный как inputAccessoryView (UIViewController, содержащий его, может стать первым ответчиком, поэтому вид виден в любое время), который содержит 2 подзаголовка. Один для UITextView и левой и правой кнопок, а другой для смайликов. Смайликов только показывают, когда левая кнопка постучала:

Emotion view

И когда один выбран, он показывает в плавающем этикетке:

Floating emotion

теперь у меня есть проблемы, чтобы изменить размер этой UITextView когда используются несколько строк. Я попытался вычислить все кадры самостоятельно, но тогда это, кажется, конфликтует с моими ограничениями каким-то странным образом. Почти всегда UITextView слишком мал или он изменяет размер только после того, как я нажму другую клавишу, чтобы обновить представление. Или UITextView становится больше по клавиатуре, или он выходит из вида, когда клавиатура отклоняется.

Я удалил все возможности изменения размера из своего кода, и я хотел бы знать, что мне нужно сделать, чтобы сделать этот размер.

В моих 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 
} 

ответ

8

Я решил эту проблему с AutoLayout.Я добавил новое ограничение, определяющее высоту моего UITextField и я устанавливаю constant этого ограничения в textView(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 
} 

Проблема у меня было то, что я устанавливал AutoLayout и UIView.frame для различных настроек, которые приводят к они сражаются.

Я идиот.

+0

Не могли бы вы добавить код для вашего текстаFieldHeightLayoutConstraint? – Stephan

+1

@Stephan Это была раскладка раскадровки, но вот она в коде: NSLayoutConstraint (item: textField, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1, constant: 30) – vrwim

+1

Это очень помогло мне! Благодаря! – Stephan

1

Я решил эту проблему с изменением размеров inputAccessoryView давно, но не устраняли проблемы с правильным размером UITextView для iOS8 до сегодняшнего дня. Вот мой пример приложение - github

Он использует кадры для iOS7 изменения размера (UITextEffectsWindow делает макет вручную, так и создание препятствий в иерархии inputAccessoryView означает создание autolayout двигателя, что приводит к autolayout отказа двигателя после странных превращений с инфом/нанами кадров) и ограничение для изменения размера iOS8. Во всяком случае, расположение представлений внутри inputAccessoryView никогда не выполняется правильно, поэтому нам нужно выполнить расчет кадров.

Example1 Example2

+0

Импортировать эту структуру и использовать ее как есть, так как мой 'inputAccessoryView' разбивает мое приложение без какой-либо полезной stacktrace. Эти дополнительные поля в таблицеView только отвлекают и добавляют дополнительный вздутие. Мне нужно изменить размер 'inputAccessoryView' с помощью' UITextView'. Можете ли вы рассказать мне, как я могу это сделать? – vrwim

+0

Это не так просто, этот пример как можно короче, чтобы он работал на iOS7 и iOS8. Не могли бы вы предоставить мне свой код, чтобы я мог проверить, что происходит не так? –

+0

Я нашел проблему, я решил ее с помощью AutoLayout и немного кода, это намного проще, чем ваше решение ... – vrwim

Смежные вопросы