Browse Source

Fix attachment cropping and spoiler text rendering, improve input views

master
Dwayne Harris 6 years ago
parent
commit
d8cc935b06
  1. 2
      Frameworks/Kingfisher
  2. 20
      elpha-ios.xcodeproj/project.pbxproj
  3. 30
      elpha-ios/AttachmentInputView.swift
  4. 77
      elpha-ios/AttachmentInputView.xib
  5. 23
      elpha-ios/AttachmentManager.swift
  6. 45
      elpha-ios/ComposeViewController.swift
  7. 4
      elpha-ios/MastodonAPI.swift
  8. 70
      elpha-ios/StatusView.swift
  9. 58
      elpha-ios/VisibilityInputView.swift
  10. 50
      elpha-ios/VisibilityInputView.xib

2
Frameworks/Kingfisher

@ -1 +1 @@
Subproject commit fbf8067218a358b470baad99a1ed3836365540f5
Subproject commit 696a8762a81af2acffc916c1753a22a5a1381d0f

20
elpha-ios.xcodeproj/project.pbxproj

@ -24,6 +24,10 @@
152FBCF2219818AD0079B3E8 /* FieldTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 152FBCF1219818AD0079B3E8 /* FieldTableViewCell.swift */; };
15341866219FF29D002F5F8A /* SettingsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15341865219FF29D002F5F8A /* SettingsManager.swift */; };
15341880219FF40F002F5F8A /* UIImageView+Effects.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1534187F219FF40F002F5F8A /* UIImageView+Effects.swift */; };
1534189E21A0E19F002F5F8A /* VisibilityInputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1534189D21A0E19F002F5F8A /* VisibilityInputView.swift */; };
153418A021A0E25A002F5F8A /* VisibilityInputView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 1534189F21A0E25A002F5F8A /* VisibilityInputView.xib */; };
153418A221A0EEAC002F5F8A /* AttachmentInputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 153418A121A0EEAC002F5F8A /* AttachmentInputView.swift */; };
153418A421A0EEED002F5F8A /* AttachmentInputView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 153418A321A0EEED002F5F8A /* AttachmentInputView.xib */; };
1539509121894A38009BA6E7 /* AlertManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1539509021894A38009BA6E7 /* AlertManager.swift */; };
156370BD219FE24200D51D42 /* Kingfisher.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 156370B0219FE22E00D51D42 /* Kingfisher.framework */; };
156370BE219FE24200D51D42 /* Kingfisher.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 156370B0219FE22E00D51D42 /* Kingfisher.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
@ -304,6 +308,10 @@
152FBCF1219818AD0079B3E8 /* FieldTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FieldTableViewCell.swift; sourceTree = "<group>"; };
15341865219FF29D002F5F8A /* SettingsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsManager.swift; sourceTree = "<group>"; };
1534187F219FF40F002F5F8A /* UIImageView+Effects.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImageView+Effects.swift"; sourceTree = "<group>"; };
1534189D21A0E19F002F5F8A /* VisibilityInputView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VisibilityInputView.swift; sourceTree = "<group>"; };
1534189F21A0E25A002F5F8A /* VisibilityInputView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = VisibilityInputView.xib; sourceTree = "<group>"; };
153418A121A0EEAC002F5F8A /* AttachmentInputView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentInputView.swift; sourceTree = "<group>"; };
153418A321A0EEED002F5F8A /* AttachmentInputView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AttachmentInputView.xib; sourceTree = "<group>"; };
1539509021894A38009BA6E7 /* AlertManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertManager.swift; sourceTree = "<group>"; };
15637094219FE22E00D51D42 /* Kingfisher.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = Kingfisher.xcodeproj; path = Frameworks/Kingfisher/Kingfisher.xcodeproj; sourceTree = "<group>"; };
1569029F219A7D75002BF61F /* ComposeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComposeViewController.swift; sourceTree = "<group>"; };
@ -353,10 +361,10 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
156370BD219FE24200D51D42 /* Kingfisher.framework in Frameworks */,
15A79B2E215C63B6007A326E /* AlamofireImage.framework in Frameworks */,
157405D1215890D700EEAAEB /* Alamofire.framework in Frameworks */,
15A79B2E215C63B6007A326E /* AlamofireImage.framework in Frameworks */,
EAD1445C219A6CAF002C5338 /* AlamofireNetworkActivityIndicator.framework in Frameworks */,
156370BD219FE24200D51D42 /* Kingfisher.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -411,6 +419,10 @@
159B5539219D11E600964AC0 /* ComposeAccessoryView.xib */,
15131EF1216D8D570092B252 /* StatusView.swift */,
15131ED7216D8C680092B252 /* StatusView.xib */,
1534189D21A0E19F002F5F8A /* VisibilityInputView.swift */,
1534189F21A0E25A002F5F8A /* VisibilityInputView.xib */,
153418A121A0EEAC002F5F8A /* AttachmentInputView.swift */,
153418A321A0EEED002F5F8A /* AttachmentInputView.xib */,
);
name = "Reusable Views";
sourceTree = "<group>";
@ -830,8 +842,10 @@
buildActionMask = 2147483647;
files = (
15960E67213145E200C38CE9 /* LaunchScreen.storyboard in Resources */,
153418A421A0EEED002F5F8A /* AttachmentInputView.xib in Resources */,
159B553A219D11E600964AC0 /* ComposeAccessoryView.xib in Resources */,
15C91A02216AB2D600D97DC3 /* AlertView.xib in Resources */,
153418A021A0E25A002F5F8A /* VisibilityInputView.xib in Resources */,
15960E64213145E200C38CE9 /* Assets.xcassets in Resources */,
157405B12151A5DA00EEAAEB /* README.md in Resources */,
15960E62213145E100C38CE9 /* Main.storyboard in Resources */,
@ -857,6 +871,7 @@
156FF0312174797E0074D9CA /* StatusTableViewController.swift in Sources */,
152FB0F8218ADC1A001D6574 /* AttachmentPageViewController.swift in Sources */,
15131EF4216DB8B90092B252 /* AccountTableViewController.swift in Sources */,
1534189E21A0E19F002F5F8A /* VisibilityInputView.swift in Sources */,
156902A0219A7D75002BF61F /* ComposeViewController.swift in Sources */,
15F998352162C0E8009E58DA /* MastodonDataManager.swift in Sources */,
15222807219D37A500D2E5A6 /* ComposeAccessoryView.swift in Sources */,
@ -869,6 +884,7 @@
15131EF2216D8D570092B252 /* StatusView.swift in Sources */,
152734D22186DC74003DB3C8 /* TimelinesViewController.swift in Sources */,
15B127A32192486200F4EF1D /* UIColor+HexString.swift in Sources */,
153418A221A0EEAC002F5F8A /* AttachmentInputView.swift in Sources */,
15341880219FF40F002F5F8A /* UIImageView+Effects.swift in Sources */,
156FF07221779C650074D9CA /* InstanceRequest.swift in Sources */,
15960E7721322C6F00C38CE9 /* Configuration.swift in Sources */,

30
elpha-ios/AttachmentInputView.swift

@ -0,0 +1,30 @@
//
// AttachmentInputView.swift
// elpha-ios
//
// Created by Dwayne Harris on 11/17/18.
// Copyright © 2018 Elpha. All rights reserved.
//
import UIKit
class AttachmentInputView: UIView {
@IBOutlet var contentView: UIView!
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
private func setup() {
Bundle.main.loadNibNamed("AttachmentInputView", owner: self, options: nil)
addSubview(contentView)
contentView.frame = self.bounds
contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
}
}

77
elpha-ios/AttachmentInputView.xib

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="AttachmentInputView" customModule="elpha_ios" customModuleProvider="target">
<connections>
<outlet property="contentView" destination="iN0-l3-epB" id="FW6-Gc-su3"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="none" translatesAutoresizingMaskIntoConstraints="NO" id="DgV-de-OI2">
<rect key="frame" x="20" y="76" width="335" height="527"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="10" minimumInteritemSpacing="10" id="pQk-XB-end">
<size key="itemSize" width="50" height="50"/>
<size key="headerReferenceSize" width="0.0" height="0.0"/>
<size key="footerReferenceSize" width="0.0" height="0.0"/>
<inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
</collectionViewFlowLayout>
</collectionView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Attachments" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xhE-rm-MSc">
<rect key="frame" x="15" y="35" width="345" height="21"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<color key="textColor" name="Text"/>
<nil key="highlightedColor"/>
</label>
<toolbar opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="q7s-jQ-GQc">
<rect key="frame" x="0.0" y="623" width="375" height="44"/>
<items>
<barButtonItem title="Add Media" id="Bj0-V6-Hhl">
<color key="tintColor" name="Text"/>
</barButtonItem>
<barButtonItem style="plain" systemItem="flexibleSpace" id="69C-R5-KwC"/>
<barButtonItem title="Cancel" id="Q8B-VF-ZJe">
<color key="tintColor" name="Text"/>
</barButtonItem>
</items>
</toolbar>
</subviews>
<color key="backgroundColor" name="Secondary"/>
<constraints>
<constraint firstItem="q7s-jQ-GQc" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="APE-kj-6aQ"/>
<constraint firstItem="DgV-de-OI2" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="20" id="Hh6-za-VeG"/>
<constraint firstItem="xhE-rm-MSc" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" constant="15" id="QfV-u7-lAG"/>
<constraint firstItem="xhE-rm-MSc" firstAttribute="top" secondItem="vUN-kp-3ea" secondAttribute="top" constant="15" id="ZpL-Ut-mnx"/>
<constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="xhE-rm-MSc" secondAttribute="trailing" constant="15" id="aNb-Y7-owY"/>
<constraint firstItem="q7s-jQ-GQc" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="trailing" id="gMo-9u-tBg"/>
<constraint firstItem="q7s-jQ-GQc" firstAttribute="bottom" secondItem="vUN-kp-3ea" secondAttribute="bottom" id="jaw-06-e0K"/>
<constraint firstItem="vUN-kp-3ea" firstAttribute="trailing" secondItem="DgV-de-OI2" secondAttribute="trailing" constant="20" id="kv4-gu-UWt"/>
<constraint firstItem="q7s-jQ-GQc" firstAttribute="top" secondItem="DgV-de-OI2" secondAttribute="bottom" constant="20" id="qmP-mN-b7z"/>
<constraint firstItem="DgV-de-OI2" firstAttribute="top" secondItem="xhE-rm-MSc" secondAttribute="bottom" constant="20" id="wVQ-yi-XqO"/>
</constraints>
<viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
</view>
</objects>
<resources>
<namedColor name="Secondary">
<color red="0.792156862745098" green="0.68627450980392157" blue="0.99215686274509807" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>
<namedColor name="Text">
<color red="0.090196078431372548" green="0.047058823529411764" blue="0.28627450980392155" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>
</resources>
</document>

23
elpha-ios/AttachmentManager.swift

@ -31,9 +31,13 @@ class AttachmentManager: NSObject {
let placeholder = UIImage(named: "Help")
let halfWidth = (view.frame.width / 2) - 1
let fullAttachmentSize = CGSize(width: view.frame.width, height: view.frame.width)
let tallAttachmentSize = CGSize(width: halfWidth, height: view.frame.width)
let smallAttachmentSize = CGSize(width: halfWidth, height: halfWidth)
let fullSize = CGSize(width: view.frame.width, height: view.frame.width)
let tallSize = CGSize(width: halfWidth, height: view.frame.width)
let smallSize = CGSize(width: halfWidth, height: halfWidth)
let fullResizingProcessor = ResizingImageProcessor(referenceSize: fullSize, mode: .aspectFill) >> CroppingImageProcessor(size: fullSize)
let tallResizingProcessor = ResizingImageProcessor(referenceSize: tallSize, mode: .aspectFill) >> CroppingImageProcessor(size: tallSize)
let smallResizingProcessor = ResizingImageProcessor(referenceSize: smallSize, mode: .aspectFill) >> CroppingImageProcessor(size: smallSize)
for subview in view.subviews as [UIView] {
subview.removeFromSuperview()
@ -44,12 +48,11 @@ class AttachmentManager: NSObject {
return
case 1:
let attachment = attachments.firstObject as! AttachmentMO
let processor = ResizingImageProcessor(referenceSize: fullAttachmentSize, mode: .aspectFill)
let imageView = UIImageView()
imageView.contentMode = UIImageView.ContentMode.scaleAspectFill
imageView.isUserInteractionEnabled = true
imageView.kf.setImage(with: attachment.url!, placeholder: placeholder, options: [.processor(processor)])
imageView.kf.setImage(with: attachment.url!, placeholder: placeholder, options: [.processor(fullResizingProcessor)])
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(attachmentTapped))
tapGestureRecognizer.delegate = self
@ -76,11 +79,10 @@ class AttachmentManager: NSObject {
for (index, imageView) in imageViews.enumerated() {
let attachment = attachments[index] as! AttachmentMO
let processor = ResizingImageProcessor(referenceSize: tallAttachmentSize, mode: .aspectFill)
imageView.contentMode = UIImageView.ContentMode.scaleAspectFill
imageView.isUserInteractionEnabled = true
imageView.kf.setImage(with: attachment.url!, placeholder: placeholder, options: [.processor(processor)])
imageView.kf.setImage(with: attachment.url!, placeholder: placeholder, options: [.processor(tallResizingProcessor)])
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(attachmentTapped))
tapGestureRecognizer.delegate = self
@ -116,9 +118,9 @@ class AttachmentManager: NSObject {
var processor: ImageProcessor
if index == 0 {
processor = ResizingImageProcessor(referenceSize: tallAttachmentSize, mode: .aspectFill)
processor = tallResizingProcessor
} else {
processor = ResizingImageProcessor(referenceSize: smallAttachmentSize, mode: .aspectFill)
processor = smallResizingProcessor
}
imageView.contentMode = UIImageView.ContentMode.scaleAspectFill
@ -166,11 +168,10 @@ class AttachmentManager: NSObject {
for (index, imageView) in imageViews.enumerated() {
let attachment = attachments[index] as! AttachmentMO
let processor = ResizingImageProcessor(referenceSize: smallAttachmentSize, mode: .aspectFill)
imageView.contentMode = UIImageView.ContentMode.scaleAspectFill
imageView.isUserInteractionEnabled = true
imageView.kf.setImage(with: attachment.url!, placeholder: placeholder, options: [.processor(processor)])
imageView.kf.setImage(with: attachment.url!, placeholder: placeholder, options: [.processor(smallResizingProcessor)])
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(attachmentTapped))
tapGestureRecognizer.delegate = self

45
elpha-ios/ComposeViewController.swift

@ -25,6 +25,10 @@ class ComposeViewController: UIViewController {
var feedbackGenerator: UINotificationFeedbackGenerator? = nil
var replyToStatus: StatusMO? = nil
var composeAccessoryView: ComposeAccessoryView? = nil
var selectedVisibility: StatusVisibility = .public
var attachmentInputView: AttachmentInputView? = nil
var visibilityInputView: VisibilityInputView? = nil
override func viewDidLoad() {
super.viewDidLoad()
@ -33,12 +37,18 @@ class ComposeViewController: UIViewController {
statusTextView.layer.cornerRadius = 10
statusTextView.layer.masksToBounds = true
statusTextView.textContainerInset = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
replyToAvatarImageView.setRoundedCorners()
composeAccessoryView = ComposeAccessoryView(frame: CGRect(x: 0.0, y: 0.0, width: self.view.bounds.size.width, height: composeAccessoryViewHeight))
composeAccessoryView = ComposeAccessoryView(frame: CGRect(x: 0, y: 0, width: self.view.bounds.size.width, height: composeAccessoryViewHeight))
composeAccessoryView!.delegate = self
composeAccessoryView!.selectedVisibility = .public
composeAccessoryView!.selectedVisibility = selectedVisibility
visibilityInputView = VisibilityInputView(frame: CGRect(x: 0, y: 0, width: self.view.bounds.size.width, height: 250))
visibilityInputView!.delegate = self
attachmentInputView = AttachmentInputView(frame: CGRect(x: 0, y: 0, width: self.view.bounds.size.width, height: 400))
statusTextView.delegate = self
statusTextView.inputAccessoryView = composeAccessoryView
@ -79,15 +89,8 @@ class ComposeViewController: UIViewController {
}
@objc func keyboardNotification(notification: NSNotification) {
if let userInfo = notification.userInfo {
let endFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue
let endFrameY = endFrame?.origin.y ?? 0
if endFrameY >= UIScreen.main.bounds.size.height {
bottomConstraint.constant = 0
} else {
bottomConstraint.constant = (endFrame?.size.height ?? 0.0) + 10
}
if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
bottomConstraint.constant = keyboardSize.height + 10
}
}
@ -103,13 +106,15 @@ extension ComposeViewController: UITextViewDelegate {
}
}
extension ComposeViewController: ComposeAccessoryViewDelegate {
extension ComposeViewController: ComposeAccessoryViewDelegate, VisibilityInputViewDelegate {
func attachmentTapped() {
AlertManager.shared.show(message: "Attachment support coming soon", category: .normal)
statusTextView.inputView = statusTextView.inputView == nil ? attachmentInputView : nil
statusTextView.reloadInputViews()
}
func visibilityTapped() {
print("Visibility tapped")
statusTextView.inputView = statusTextView.inputView == nil ? visibilityInputView : nil
statusTextView.reloadInputViews()
}
func tootTapped() {
@ -117,7 +122,7 @@ extension ComposeViewController: ComposeAccessoryViewDelegate {
if !content.isEmpty && content.count <= characterLimit {
feedbackGenerator?.prepare()
MastodonAPI.postStatus(content: content, replyToID: replyToStatus?.id, spoilerText: contentWarningTextField.text) { error in
MastodonAPI.postStatus(content: content, replyToID: replyToStatus?.id, spoilerText: contentWarningTextField.text, visibility: selectedVisibility) { error in
guard error == nil else {
self.feedbackGenerator?.notificationOccurred(.error)
AlertManager.shared.show(message: "Couldn't toot!", category: .error)
@ -125,7 +130,7 @@ extension ComposeViewController: ComposeAccessoryViewDelegate {
}
self.feedbackGenerator?.notificationOccurred(.success)
AlertManager.shared.show(message: "Toot!")
AlertManager.shared.show(message: "Toot!", category: .normal)
self.statusTextView.text = ""
self.contentWarningTextField.text = ""
@ -134,4 +139,12 @@ extension ComposeViewController: ComposeAccessoryViewDelegate {
}
}
}
func visibilitySelected(visibility: StatusVisibility) {
selectedVisibility = visibility
composeAccessoryView?.selectedVisibility = visibility
statusTextView.inputView = nil
statusTextView.reloadInputViews()
}
}

4
elpha-ios/MastodonAPI.swift

@ -29,8 +29,8 @@ enum AttachmentType: String {
case unknown, image, gifv, video
}
enum StatusVisibility: String {
case direct, `private`, unlisted, `public`
enum StatusVisibility: String, CaseIterable {
case `public`, unlisted, `private`, direct
}
public class PaginationItem: NSObject, NSCoding {

70
elpha-ios/StatusView.swift

@ -269,40 +269,42 @@ class StatusView: UIView {
if let content = status.content {
contentTextView.attributedText = content.htmlAttributed(size: 15.0)
if status.hidden && spoilerView == nil {
let spoilerText = UILabel(frame: contentTextView.frame)
spoilerText.textColor = UIColor(named: "Primary")
spoilerText.font = UIFont.systemFont(ofSize: 15, weight: .bold)
spoilerText.textAlignment = .center
spoilerText.text = status.spoilerText
spoilerText.numberOfLines = 0
spoilerText.translatesAutoresizingMaskIntoConstraints = false
let blurEffectView = UIVisualEffectView(effect: UIBlurEffect(style: UIBlurEffect.Style.light))
blurEffectView.translatesAutoresizingMaskIntoConstraints = false
blurEffectView.contentView.addSubview(spoilerText)
NSLayoutConstraint.activate([
spoilerText.leadingAnchor.constraint(equalTo: blurEffectView.leadingAnchor),
spoilerText.trailingAnchor.constraint(equalTo: blurEffectView.trailingAnchor),
spoilerText.centerYAnchor.constraint(equalTo: blurEffectView.centerYAnchor),
])
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.reveal))
tapGesture.numberOfTapsRequired = 1
tapGesture.numberOfTouchesRequired = 1
blurEffectView.addGestureRecognizer(tapGesture)
blurEffectView.isUserInteractionEnabled = true
self.spoilerView = blurEffectView
self.contentView.addSubview(blurEffectView)
NSLayoutConstraint.activate([
blurEffectView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
blurEffectView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
blurEffectView.topAnchor.constraint(equalTo: contentTextView.topAnchor),
blurEffectView.bottomAnchor.constraint(equalTo: detailsView.topAnchor),
])
if status.hidden {
if spoilerView == nil {
let spoilerText = UILabel(frame: contentTextView.frame)
spoilerText.textColor = UIColor(named: "Primary")
spoilerText.font = UIFont.systemFont(ofSize: 15, weight: .bold)
spoilerText.textAlignment = .center
spoilerText.text = status.spoilerText
spoilerText.numberOfLines = 0
spoilerText.translatesAutoresizingMaskIntoConstraints = false
let blurEffectView = UIVisualEffectView(effect: UIBlurEffect(style: UIBlurEffect.Style.light))
blurEffectView.translatesAutoresizingMaskIntoConstraints = false
blurEffectView.contentView.addSubview(spoilerText)
NSLayoutConstraint.activate([
spoilerText.leadingAnchor.constraint(equalTo: blurEffectView.leadingAnchor),
spoilerText.trailingAnchor.constraint(equalTo: blurEffectView.trailingAnchor),
spoilerText.centerYAnchor.constraint(equalTo: blurEffectView.centerYAnchor),
])
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.reveal))
tapGesture.numberOfTapsRequired = 1
tapGesture.numberOfTouchesRequired = 1
blurEffectView.addGestureRecognizer(tapGesture)
blurEffectView.isUserInteractionEnabled = true
self.spoilerView = blurEffectView
self.contentView.addSubview(blurEffectView)
NSLayoutConstraint.activate([
blurEffectView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
blurEffectView.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
blurEffectView.topAnchor.constraint(equalTo: contentTextView.topAnchor),
blurEffectView.bottomAnchor.constraint(equalTo: detailsView.topAnchor),
])
}
} else {
if let spoilerView = spoilerView {
spoilerView.removeFromSuperview()

58
elpha-ios/VisibilityInputView.swift

@ -0,0 +1,58 @@
//
// VisibilityInputView.swift
// elpha-ios
//
// Created by Dwayne Harris on 11/17/18.
// Copyright © 2018 Elpha. All rights reserved.
//
import UIKit
protocol VisibilityInputViewDelegate {
func visibilitySelected(visibility: StatusVisibility)
}
class VisibilityInputView: UIView {
@IBOutlet var contentView: UIView!
@IBOutlet var visibilityPickerView: UIPickerView!
public var delegate: VisibilityInputViewDelegate? = nil
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
private func setup() {
Bundle.main.loadNibNamed("VisibilityInputView", owner: self, options: nil)
addSubview(contentView)
contentView.frame = self.bounds
contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
visibilityPickerView.delegate = self
visibilityPickerView.dataSource = self
}
}
extension VisibilityInputView: UIPickerViewDelegate, UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return StatusVisibility.allCases.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return StatusVisibility.allCases[row].rawValue.capitalized
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
delegate?.visibilitySelected(visibility: StatusVisibility.allCases[row])
}
}

50
elpha-ios/VisibilityInputView.xib

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="VisibilityInputView" customModule="elpha_ios" customModuleProvider="target">
<connections>
<outlet property="contentView" destination="iN0-l3-epB" id="7pz-hP-ZWx"/>
<outlet property="visibilityPickerView" destination="eBW-A5-bzo" id="0jd-DN-JX5"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<pickerView contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="eBW-A5-bzo">
<rect key="frame" x="0.0" y="258.5" width="375" height="150"/>
<color key="tintColor" name="Text"/>
<constraints>
<constraint firstAttribute="height" constant="150" id="PnD-GD-JgW"/>
</constraints>
</pickerView>
</subviews>
<color key="backgroundColor" name="Secondary"/>
<constraints>
<constraint firstItem="eBW-A5-bzo" firstAttribute="trailing" secondItem="vUN-kp-3ea" secondAttribute="trailing" id="Jvq-QQ-FZw"/>
<constraint firstItem="eBW-A5-bzo" firstAttribute="leading" secondItem="vUN-kp-3ea" secondAttribute="leading" id="Q0U-OE-d4i"/>
<constraint firstItem="eBW-A5-bzo" firstAttribute="centerY" secondItem="iN0-l3-epB" secondAttribute="centerY" id="T6B-SN-bx7"/>
</constraints>
<viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
</view>
</objects>
<resources>
<namedColor name="Secondary">
<color red="0.792156862745098" green="0.68627450980392157" blue="0.99215686274509807" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>
<namedColor name="Text">
<color red="0.090196078431372548" green="0.047058823529411764" blue="0.28627450980392155" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>
</resources>
</document>
Loading…
Cancel
Save