Switch to new text view placeholder implementation

This commit is contained in:
Shadowfacts 2018-09-29 22:28:17 -04:00
parent 3da1a7badd
commit db1be505e0
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
4 changed files with 16 additions and 74 deletions

View File

@ -82,7 +82,6 @@
D663626C21361C6700C9CBA2 /* Account+Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = D663626B21361C6700C9CBA2 /* Account+Preferences.swift */; }; D663626C21361C6700C9CBA2 /* Account+Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = D663626B21361C6700C9CBA2 /* Account+Preferences.swift */; };
D663626F213632A000C9CBA2 /* Compose.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D663626E213632A000C9CBA2 /* Compose.storyboard */; }; D663626F213632A000C9CBA2 /* Compose.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D663626E213632A000C9CBA2 /* Compose.storyboard */; };
D66362712136338600C9CBA2 /* ComposeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66362702136338600C9CBA2 /* ComposeViewController.swift */; }; D66362712136338600C9CBA2 /* ComposeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66362702136338600C9CBA2 /* ComposeViewController.swift */; };
D66362732136FFC600C9CBA2 /* UITextView+Placeholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66362722136FFC600C9CBA2 /* UITextView+Placeholder.swift */; };
D66362752137068A00C9CBA2 /* Visibility+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66362742137068A00C9CBA2 /* Visibility+Helpers.swift */; }; D66362752137068A00C9CBA2 /* Visibility+Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D66362742137068A00C9CBA2 /* Visibility+Helpers.swift */; };
D667E5E12134937B0057A976 /* StatusTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D667E5E02134937B0057A976 /* StatusTableViewCell.xib */; }; D667E5E12134937B0057A976 /* StatusTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D667E5E02134937B0057A976 /* StatusTableViewCell.xib */; };
D667E5E3213499F70057A976 /* Profile.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D667E5E2213499F70057A976 /* Profile.storyboard */; }; D667E5E3213499F70057A976 /* Profile.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D667E5E2213499F70057A976 /* Profile.storyboard */; };
@ -245,7 +244,6 @@
D663626B21361C6700C9CBA2 /* Account+Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Account+Preferences.swift"; sourceTree = "<group>"; }; D663626B21361C6700C9CBA2 /* Account+Preferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Account+Preferences.swift"; sourceTree = "<group>"; };
D663626E213632A000C9CBA2 /* Compose.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Compose.storyboard; sourceTree = "<group>"; }; D663626E213632A000C9CBA2 /* Compose.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Compose.storyboard; sourceTree = "<group>"; };
D66362702136338600C9CBA2 /* ComposeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeViewController.swift; sourceTree = "<group>"; }; D66362702136338600C9CBA2 /* ComposeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeViewController.swift; sourceTree = "<group>"; };
D66362722136FFC600C9CBA2 /* UITextView+Placeholder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITextView+Placeholder.swift"; sourceTree = "<group>"; };
D66362742137068A00C9CBA2 /* Visibility+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Visibility+Helpers.swift"; sourceTree = "<group>"; }; D66362742137068A00C9CBA2 /* Visibility+Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Visibility+Helpers.swift"; sourceTree = "<group>"; };
D667E5E02134937B0057A976 /* StatusTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = StatusTableViewCell.xib; sourceTree = "<group>"; }; D667E5E02134937B0057A976 /* StatusTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = StatusTableViewCell.xib; sourceTree = "<group>"; };
D667E5E2213499F70057A976 /* Profile.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Profile.storyboard; sourceTree = "<group>"; }; D667E5E2213499F70057A976 /* Profile.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Profile.storyboard; sourceTree = "<group>"; };
@ -576,7 +574,6 @@
D667E5F02134D5050057A976 /* UIViewController+Delegates.swift */, D667E5F02134D5050057A976 /* UIViewController+Delegates.swift */,
D667E5F72135C3040057A976 /* Mastodon+Equatable.swift */, D667E5F72135C3040057A976 /* Mastodon+Equatable.swift */,
D663626B21361C6700C9CBA2 /* Account+Preferences.swift */, D663626B21361C6700C9CBA2 /* Account+Preferences.swift */,
D66362722136FFC600C9CBA2 /* UITextView+Placeholder.swift */,
D66362742137068A00C9CBA2 /* Visibility+Helpers.swift */, D66362742137068A00C9CBA2 /* Visibility+Helpers.swift */,
D6333B362137838300CE884A /* AttributedString+Trim.swift */, D6333B362137838300CE884A /* AttributedString+Trim.swift */,
D6333B782139AEFD00CE884A /* Date+TimeAgo.swift */, D6333B782139AEFD00CE884A /* Date+TimeAgo.swift */,
@ -985,7 +982,6 @@
D641C777213CAA9E004B4513 /* ActionNotificationTableViewCell.swift in Sources */, D641C777213CAA9E004B4513 /* ActionNotificationTableViewCell.swift in Sources */,
D64D0AB12128D9AE005A6F37 /* OnboardingViewController.swift in Sources */, D64D0AB12128D9AE005A6F37 /* OnboardingViewController.swift in Sources */,
D663626821360E2C00C9CBA2 /* PreferencesTableViewController.swift in Sources */, D663626821360E2C00C9CBA2 /* PreferencesTableViewController.swift in Sources */,
D66362732136FFC600C9CBA2 /* UITextView+Placeholder.swift in Sources */,
D64F80E2215875CC00BEF393 /* XCBActionType.swift in Sources */, D64F80E2215875CC00BEF393 /* XCBActionType.swift in Sources */,
D66362752137068A00C9CBA2 /* Visibility+Helpers.swift in Sources */, D66362752137068A00C9CBA2 /* Visibility+Helpers.swift in Sources */,
D646C95A213B5D0500269FB5 /* LargeImageInteractionController.swift in Sources */, D646C95A213B5D0500269FB5 /* LargeImageInteractionController.swift in Sources */,

View File

@ -1,66 +0,0 @@
//
// PlaceholderTextView.swift
// Tusker
//
// Created by Shadowfacts on 8/29/18.
// Copyright © 2018 Shadowfacts. All rights reserved.
//
import UIKit
// Source: https://finnwea.com/blog/adding-placeholders-to-uitextviews-in-swift/
extension UITextView: UITextViewDelegate {
override open var bounds: CGRect {
didSet {
resizePlaceholder()
}
}
var placeholder: String? {
get {
return (viewWithTag(100) as? UILabel)?.text
}
set {
if let placeholderLabel = viewWithTag(100) as? UILabel {
placeholderLabel.text = newValue
placeholderLabel.sizeToFit()
} else {
guard let newValue = newValue else { return }
addPlaceholder(newValue)
}
}
}
public func textViewDidChange(_ textView: UITextView) {
if let placeholderLabel = viewWithTag(100) as? UILabel {
placeholderLabel.isHidden = !text.isEmpty
}
}
private func resizePlaceholder() {
guard let placeholderLabel = viewWithTag(100) as? UILabel else { fatalError() }
let labelX = textContainer.lineFragmentPadding
let labelY = textContainerInset.top
let labelWidth = frame.width - (labelX * 2)
let labelHeight = placeholderLabel.frame.height
placeholderLabel.frame = CGRect(x: labelX, y: labelY, width: labelWidth, height: labelHeight)
}
private func addPlaceholder(_ placeholderText: String) {
let placeholderLabel = UILabel()
placeholderLabel.text = placeholderText
placeholderLabel.sizeToFit()
placeholderLabel.font = font
placeholderLabel.textColor = .lightGray
placeholderLabel.tag = 100
placeholderLabel.isHighlighted = !text.isEmpty
addSubview(placeholderLabel)
resizePlaceholder()
delegate = self
}
}

View File

@ -144,13 +144,21 @@
</stackView> </stackView>
</subviews> </subviews>
</stackView> </stackView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="What is on your mind?" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sCM-XV-u2f">
<rect key="frame" x="20.5" y="186.5" width="170" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
</subviews> </subviews>
<constraints> <constraints>
<constraint firstAttribute="trailing" secondItem="WID-nQ-ZzS" secondAttribute="trailing" constant="16" id="0Sy-jt-Ddv"/> <constraint firstAttribute="trailing" secondItem="WID-nQ-ZzS" secondAttribute="trailing" constant="16" id="0Sy-jt-Ddv"/>
<constraint firstItem="bGo-tx-r56" firstAttribute="height" secondItem="L3H-aB-fGr" secondAttribute="height" constant="-68" id="5Xh-ao-jAN"/> <constraint firstItem="bGo-tx-r56" firstAttribute="height" secondItem="L3H-aB-fGr" secondAttribute="height" constant="-68" id="5Xh-ao-jAN"/>
<constraint firstItem="WID-nQ-ZzS" firstAttribute="leading" secondItem="L3H-aB-fGr" secondAttribute="leading" constant="16" id="8Aw-l2-092"/> <constraint firstItem="WID-nQ-ZzS" firstAttribute="leading" secondItem="L3H-aB-fGr" secondAttribute="leading" constant="16" id="8Aw-l2-092"/>
<constraint firstItem="sCM-XV-u2f" firstAttribute="top" secondItem="gQU-rc-mM7" secondAttribute="top" constant="8" id="8ws-rN-cVr"/>
<constraint firstItem="WID-nQ-ZzS" firstAttribute="top" secondItem="L3H-aB-fGr" secondAttribute="top" constant="16" id="CYg-ft-CAr"/> <constraint firstItem="WID-nQ-ZzS" firstAttribute="top" secondItem="L3H-aB-fGr" secondAttribute="top" constant="16" id="CYg-ft-CAr"/>
<constraint firstAttribute="bottom" secondItem="WID-nQ-ZzS" secondAttribute="bottom" id="yTD-d9-Cr8"/> <constraint firstAttribute="bottom" secondItem="WID-nQ-ZzS" secondAttribute="bottom" id="yTD-d9-Cr8"/>
<constraint firstItem="sCM-XV-u2f" firstAttribute="leading" secondItem="gQU-rc-mM7" secondAttribute="leading" constant="4.5" id="yTj-uC-5Qj"/>
</constraints> </constraints>
</scrollView> </scrollView>
<progressView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" progressViewStyle="bar" progress="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="qAh-id-u7z" customClass="SteppedProgressView" customModule="Tusker" customModuleProvider="target"> <progressView opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="750" progressViewStyle="bar" progress="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="qAh-id-u7z" customClass="SteppedProgressView" customModule="Tusker" customModuleProvider="target">
@ -188,6 +196,7 @@
<outlet property="inReplyToUsernameLabel" destination="neM-1F-PcJ" id="Lej-ut-yp9"/> <outlet property="inReplyToUsernameLabel" destination="neM-1F-PcJ" id="Lej-ut-yp9"/>
<outlet property="mediaStackView" destination="gcH-tf-prn" id="oM2-hc-rXY"/> <outlet property="mediaStackView" destination="gcH-tf-prn" id="oM2-hc-rXY"/>
<outlet property="paddingView" destination="VuB-eX-IiL" id="wDo-4O-g30"/> <outlet property="paddingView" destination="VuB-eX-IiL" id="wDo-4O-g30"/>
<outlet property="placeholderLabel" destination="sCM-XV-u2f" id="cVa-Mf-1cO"/>
<outlet property="postButton" destination="wg4-nL-Q7B" id="6EL-Dd-jPb"/> <outlet property="postButton" destination="wg4-nL-Q7B" id="6EL-Dd-jPb"/>
<outlet property="progressView" destination="qAh-id-u7z" id="sw0-dq-eNa"/> <outlet property="progressView" destination="qAh-id-u7z" id="sw0-dq-eNa"/>
<outlet property="scrollView" destination="L3H-aB-fGr" id="kbS-H5-K2I"/> <outlet property="scrollView" destination="L3H-aB-fGr" id="kbS-H5-K2I"/>

View File

@ -37,6 +37,7 @@ class ComposeViewController: UIViewController {
@IBOutlet weak var inReplyToContentLabel: StatusContentLabel! @IBOutlet weak var inReplyToContentLabel: StatusContentLabel!
@IBOutlet weak var inReplyToLabel: UILabel! @IBOutlet weak var inReplyToLabel: UILabel!
@IBOutlet weak var statusTextView: UITextView! @IBOutlet weak var statusTextView: UITextView!
@IBOutlet weak var placeholderLabel: UILabel!
@IBOutlet weak var charactersRemainingLabel: UILabel! @IBOutlet weak var charactersRemainingLabel: UILabel!
@IBOutlet weak var visibilityButton: UIButton! @IBOutlet weak var visibilityButton: UIButton!
@IBOutlet weak var postButton: UIButton! @IBOutlet weak var postButton: UIButton!
@ -70,7 +71,6 @@ class ComposeViewController: UIViewController {
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
statusTextView.placeholder = "What is on your mind?"
statusTextView.layer.cornerRadius = 5 statusTextView.layer.cornerRadius = 5
statusTextView.layer.masksToBounds = true statusTextView.layer.masksToBounds = true
statusTextView.delegate = self statusTextView.delegate = self
@ -102,7 +102,6 @@ class ComposeViewController: UIViewController {
statusTextView.text = "@\(inReplyTo.account.acct) " statusTextView.text = "@\(inReplyTo.account.acct) "
} }
statusTextView.text += inReplyTo.mentions.filter({ $0.id != MastodonController.shared.account.id }).map({ "@\($0.acct) " }).joined() statusTextView.text += inReplyTo.mentions.filter({ $0.id != MastodonController.shared.account.id }).map({ "@\($0.acct) " }).joined()
statusTextView.textViewDidChange(statusTextView)
contentWarning = inReplyTo.sensitive contentWarning = inReplyTo.sensitive
contentWarningTextField.text = inReplyTo.spoilerText contentWarningTextField.text = inReplyTo.spoilerText
visibility = inReplyTo.visibility visibility = inReplyTo.visibility
@ -113,14 +112,13 @@ class ComposeViewController: UIViewController {
if let mentioningAcct = mentioningAcct { if let mentioningAcct = mentioningAcct {
statusTextView.text += "@\(mentioningAcct) " statusTextView.text += "@\(mentioningAcct) "
statusTextView.textViewDidChange(statusTextView)
} }
if let text = text { if let text = text {
statusTextView.text += text statusTextView.text += text
statusTextView.textViewDidChange(statusTextView)
} }
updateCharactersRemaining() updateCharactersRemaining()
updatePlaceholder()
progressView.progress = 0 progressView.progress = 0
} }
@ -151,6 +149,10 @@ class ComposeViewController: UIViewController {
charactersRemainingLabel.text = remaining.description charactersRemainingLabel.text = remaining.description
} }
func updatePlaceholder() {
placeholderLabel.isHidden = !statusTextView.text.isEmpty
}
// MARK: - Navigation // MARK: - Navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
@ -299,6 +301,7 @@ extension ComposeViewController: UITextFieldDelegate {
extension ComposeViewController: UITextViewDelegate { extension ComposeViewController: UITextViewDelegate {
func textViewDidChange(_ textView: UITextView) { func textViewDidChange(_ textView: UITextView) {
updateCharactersRemaining() updateCharactersRemaining()
updatePlaceholder()
} }
} }