2017-01-17 3 views
0

インタフェースビルダーのテキストのインセットを調整できるように、IBDesignable UITextViewを作成するにはどうすればよいですか?私は等を検査可能な特性topInsetbottomInsetを追加しましたが、今私は実際には変更はIBUITextView IBDesignable Padding

import UIKit 

private let kPlaceholderTextViewInsetSpan: CGFloat = 8 

@IBDesignable class UIDesignableTextView: UITextView { 
    // variables 

    @IBInspectable var topInset: CGFloat = 0.0 
    @IBInspectable var leftInset: CGFloat = 0.0 
    @IBInspectable var bottomInset: CGFloat = 0.0 
    @IBInspectable var rightInset: CGFloat = 0.0 

    var insets: UIEdgeInsets { 
     get { 
      return UIEdgeInsetsMake(topInset, leftInset, bottomInset, rightInset) 
     } 
     set { 
      topInset = newValue.top 
      leftInset = newValue.left 
      bottomInset = newValue.bottom 
      rightInset = newValue.right 
     } 
    } 

    @IBInspectable var placeholder: NSString? { didSet { setNeedsDisplay() } } 
    @IBInspectable var placeholderColor: UIColor = UIColor.lightGray 

    override var text: String! { didSet { setNeedsDisplay() } } 

    override var attributedText: NSAttributedString! { didSet { setNeedsDisplay() } } 

    override var contentInset: UIEdgeInsets { didSet { setNeedsDisplay() } } 

    override var font: UIFont? { didSet { setNeedsDisplay() } } 

    override var textAlignment: NSTextAlignment { didSet { setNeedsDisplay() } } 

    // MARK: - Lifecycle 

    /** Override coder init, for IB/XIB compatibility */ 
    #if !TARGET_INTERFACE_BUILDER 
    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
     listenForTextChangedNotifications() 
    } 

    /** Override common init, for manual allocation */ 
    override init(frame: CGRect, textContainer: NSTextContainer?) { 
     super.init(frame: frame, textContainer: textContainer) 
     listenForTextChangedNotifications() 
    } 
    #endif 

    /** Initializes the placeholder text view, waiting for a notification of text changed */ 
    func listenForTextChangedNotifications() { 
     NotificationCenter.default.addObserver(self, selector: #selector(UIDesignableTextView.textChangedForPlaceholderTextView(_:)), name:NSNotification.Name.UITextViewTextDidChange , object: self) 
     NotificationCenter.default.addObserver(self, selector: #selector(UIDesignableTextView.textChangedForPlaceholderTextView(_:)), name:NSNotification.Name.UITextViewTextDidBeginEditing , object: self) 
    } 

    /** willMoveToWindow will get called with a nil argument when the window is about to dissapear */ 
    override func willMove(toWindow newWindow: UIWindow?) { 
     super.willMove(toWindow: newWindow) 
     if newWindow == nil { NotificationCenter.default.removeObserver(self) } 
     else { listenForTextChangedNotifications() } 
    } 

      func textChangedForPlaceholderTextView(_ notification: Notification) { 
     setNeedsDisplay() 
     setNeedsLayout() 
    } 

    override func draw(_ rect: CGRect) { 
     super.draw(rect) 

     if text.characters.count == 0 && self.placeholder != nil { 
      let baseRect = placeholderBoundsContainedIn(self.bounds) 
      let font = self.font ?? self.typingAttributes[NSFontAttributeName] as? UIFont ?? UIFont.systemFont(ofSize: UIFont.systemFontSize) 

      self.placeholderColor.set() 

      var customParagraphStyle: NSMutableParagraphStyle! 
      if let defaultParagraphStyle = typingAttributes[NSParagraphStyleAttributeName] as? NSParagraphStyle { 
       customParagraphStyle = defaultParagraphStyle.mutableCopy() as! NSMutableParagraphStyle 
      } else { customParagraphStyle = NSMutableParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle } 
      // set attributes 
      customParagraphStyle.lineBreakMode = NSLineBreakMode.byTruncatingTail 
      customParagraphStyle.alignment = self.textAlignment 
      let attributes = [NSFontAttributeName: font, NSParagraphStyleAttributeName: customParagraphStyle.copy() as! NSParagraphStyle, NSForegroundColorAttributeName: self.placeholderColor] 
      // draw in rect. 
      self.placeholder?.draw(in: baseRect, withAttributes: attributes) 
     } 
    } 

    func placeholderBoundsContainedIn(_ containerBounds: CGRect) -> CGRect { 
     // get the base rect with content insets. 
     let baseRect = UIEdgeInsetsInsetRect(containerBounds, UIEdgeInsetsMake(kPlaceholderTextViewInsetSpan, kPlaceholderTextViewInsetSpan/2.0, 0, 0)) 

     // adjust typing and selection attributes 
     if let paragraphStyle = typingAttributes[NSParagraphStyleAttributeName] as? NSParagraphStyle { 
      baseRect.offsetBy(dx: paragraphStyle.headIndent, dy: paragraphStyle.firstLineHeadIndent) 
     } 

     return baseRect 
    } 

答えて

1

に反映されている。これは、あなたが必要とするすべてであるようなUITextViewのインセットを更新する方法、トラブルのフィギュアを持っています行うには:

import UIKit 

@IBDesignable class TextViewWithInsets: UITextView { 

    @IBInspectable var topInset: CGFloat = 0 { 
     didSet { 
      self.contentInset = UIEdgeInsetsMake(topInset, self.contentInset.left, self.contentInset.bottom, self.contentInset.right) 
     } 
    } 

    @IBInspectable var bottmInset: CGFloat = 0 { 
     didSet { 
      self.contentInset = UIEdgeInsetsMake(self.contentInset.top, self.contentInset.left, bottmInset, self.contentInset.right) 
     } 
    } 

    @IBInspectable var leftInset: CGFloat = 0 { 
     didSet { 
      self.contentInset = UIEdgeInsetsMake(self.contentInset.top, leftInset, self.contentInset.bottom, self.contentInset.right) 
     } 
    } 

    @IBInspectable var rightInset: CGFloat = 0 { 
     didSet { 
      self.contentInset = UIEdgeInsetsMake(self.contentInset.top, self.contentInset.left, self.contentInset.bottom, rightInset) 
     } 
    } 
} 

を見てわかるように、これらは私が作成したUITextViewTextViewWithInsetsサブクラスのプロパティです。プロパティメソッドのdidSet部分をオーバーライドする必要があります。 attributes inspector in IB for new class

これらの4つのプロパティ(インターフェイスインプット、ボトムインセット、左インセット、右インセット)は、Interface BuilderでストーリーボードにTextViewオブジェクトが設定されていることを確認してくださいTextViewWithInsetsとなるように指定してください。Set class of Text View object in storyboard to custom class

+0

これはあなたの質問にお答えしましたか?あなたがまだこれを理解しようとしているのであれば教えてください。 – eschos24