forked from shadowfacts/Tusker
Switch to new text view placeholder implementation
This commit is contained in:
parent
3da1a7badd
commit
db1be505e0
|
@ -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 */,
|
||||||
|
|
|
@ -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
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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"/>
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue