Add 3d touch peek/pop navigation
This commit is contained in:
parent
76beb8ddbe
commit
d0feece606
|
@ -125,6 +125,7 @@
|
|||
D6D4DDDA212518A200E1C4BB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D6D4DDD8212518A200E1C4BB /* LaunchScreen.storyboard */; };
|
||||
D6D4DDE5212518A200E1C4BB /* TuskerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D4DDE4212518A200E1C4BB /* TuskerTests.swift */; };
|
||||
D6D4DDF0212518A200E1C4BB /* TuskerUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6D4DDEF212518A200E1C4BB /* TuskerUITests.swift */; };
|
||||
D6E0DC8E216EDF1E00369478 /* Previewing.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E0DC8D216EDF1E00369478 /* Previewing.swift */; };
|
||||
D6E6F26321603F8B006A8599 /* CharacterCounter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E6F26221603F8B006A8599 /* CharacterCounter.swift */; };
|
||||
D6E6F26521604242006A8599 /* CharacterCounterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6E6F26421604242006A8599 /* CharacterCounterTests.swift */; };
|
||||
D6F953EC212519E700CF0F2B /* TimelineTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6F953EB212519E700CF0F2B /* TimelineTableViewController.swift */; };
|
||||
|
@ -318,6 +319,7 @@
|
|||
D6D4DDEB212518A200E1C4BB /* TuskerUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TuskerUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D6D4DDEF212518A200E1C4BB /* TuskerUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TuskerUITests.swift; sourceTree = "<group>"; };
|
||||
D6D4DDF1212518A200E1C4BB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
D6E0DC8D216EDF1E00369478 /* Previewing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Previewing.swift; sourceTree = "<group>"; };
|
||||
D6E6F26221603F8B006A8599 /* CharacterCounter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CharacterCounter.swift; sourceTree = "<group>"; };
|
||||
D6E6F26421604242006A8599 /* CharacterCounterTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CharacterCounterTests.swift; sourceTree = "<group>"; };
|
||||
D6F953EB212519E700CF0F2B /* TimelineTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineTableViewController.swift; sourceTree = "<group>"; };
|
||||
|
@ -672,7 +674,6 @@
|
|||
D6BED1722126661300F02DA0 /* Views */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D621544921682AC60003D87D /* Tab */,
|
||||
04496BD621625361001F1B23 /* ContentLabel.swift */,
|
||||
D6C693F82162E4DB007D6A6D /* StatusContentLabel.swift */,
|
||||
D6C94D882139E6EC00CB5196 /* AttachmentView.swift */,
|
||||
|
@ -683,6 +684,7 @@
|
|||
D641C78A213DD926004B4513 /* Status */,
|
||||
D641C78B213DD92F004B4513 /* Profile Header */,
|
||||
D641C78C213DD937004B4513 /* Notifications */,
|
||||
D621544921682AC60003D87D /* Tab */,
|
||||
D6C693CB2161256B007D6A6D /* Silent Action Permissions */,
|
||||
);
|
||||
path = Views;
|
||||
|
@ -702,6 +704,7 @@
|
|||
children = (
|
||||
D6C693FB2162FE6F007D6A6D /* LoadingViewController.swift */,
|
||||
D6C693FD2162FEEA007D6A6D /* UIViewController+Children.swift */,
|
||||
D6E0DC8D216EDF1E00369478 /* Previewing.swift */,
|
||||
);
|
||||
path = Utilities;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1117,6 +1120,7 @@
|
|||
D663626421360D2300C9CBA2 /* AvatarStyle.swift in Sources */,
|
||||
D679C09F215850EF00DA27FE /* XCBActions.swift in Sources */,
|
||||
D6538945214D6D7500E3CEFC /* TableViewSwipeActionProvider.swift in Sources */,
|
||||
D6E0DC8E216EDF1E00369478 /* Previewing.swift in Sources */,
|
||||
D6BED174212667E900F02DA0 /* StatusTableViewCell.swift in Sources */,
|
||||
D64D0AAD2128D88B005A6F37 /* LocalData.swift in Sources */,
|
||||
D6C94D892139E6EC00CB5196 /* AttachmentView.swift in Sources */,
|
||||
|
|
|
@ -44,6 +44,10 @@ class ImageCache {
|
|||
}
|
||||
}
|
||||
|
||||
func get(_ url: URL) -> UIImage? {
|
||||
return try? storage.object(forKey: url.absoluteString)
|
||||
}
|
||||
|
||||
func cancel(_ url: URL) {
|
||||
requests[url]?.cancel()
|
||||
}
|
||||
|
|
|
@ -52,6 +52,8 @@ class ConversationViewController: UITableViewController {
|
|||
self.tableView.scrollToRow(at: indexPath, at: .middle, animated: false)
|
||||
}
|
||||
}
|
||||
|
||||
registerForPreviewing(with: self, sourceView: view)
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
|
|
|
@ -15,10 +15,22 @@ protocol LargeImageViewControllerDelegate {
|
|||
|
||||
class LargeImageViewController: UIViewController, UIScrollViewDelegate {
|
||||
|
||||
static func create(image: UIImage, description: String?) -> LargeImageViewController {
|
||||
static func create(image: UIImage, description: String?, sourceView: UIView, sourceViewController: UIViewController) -> LargeImageViewController {
|
||||
guard let vc = UIStoryboard(name: "LargeImage", bundle: nil).instantiateInitialViewController() as? LargeImageViewController else { fatalError() }
|
||||
vc.image = image
|
||||
vc.imageDescription = description
|
||||
var frame = sourceView.convert(sourceView.bounds, to: sourceViewController.view)
|
||||
if let scrollView = sourceViewController.view as? UIScrollView {
|
||||
let scale = scrollView.zoomScale
|
||||
let width = frame.width * scale
|
||||
let height = frame.height * scale
|
||||
let x = frame.minX * scale - scrollView.contentOffset.x + scrollView.frame.minX
|
||||
let y = frame.minY * scale - scrollView.contentOffset.y + scrollView.frame.minY
|
||||
frame = CGRect(x: x, y: y, width: width, height: height)
|
||||
}
|
||||
vc.originFrame = frame
|
||||
vc.originCornerRadius = sourceView.layer.cornerRadius
|
||||
vc.transitioningDelegate = sourceViewController
|
||||
return vc
|
||||
}
|
||||
|
||||
|
|
|
@ -52,6 +52,8 @@ class NotificationsTableViewController: UITableViewController {
|
|||
self.newer = pagination?.newer
|
||||
self.older = pagination?.older
|
||||
}
|
||||
|
||||
registerForPreviewing(with: self, sourceView: view)
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
|
|
|
@ -76,6 +76,8 @@ class TimelineTableViewController: UITableViewController {
|
|||
self.newer = pagination?.newer
|
||||
self.older = pagination?.older
|
||||
}
|
||||
|
||||
registerForPreviewing(with: self, sourceView: view)
|
||||
}
|
||||
|
||||
override func viewWillAppear(_ animated: Bool) {
|
||||
|
|
|
@ -0,0 +1,84 @@
|
|||
//
|
||||
// PreviewViewControllerProvider.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 10/10/18.
|
||||
// Copyright © 2018 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
enum PreviewCommitType {
|
||||
case nav
|
||||
case modal
|
||||
}
|
||||
|
||||
protocol PreviewViewControllerProvider {
|
||||
|
||||
func getPreviewViewController(forLocation location: CGPoint, sourceViewController: UIViewController) -> UIViewController?
|
||||
|
||||
func getPreviewCommitType(forViewController viewController: UIViewController) -> PreviewCommitType
|
||||
|
||||
}
|
||||
|
||||
extension PreviewViewControllerProvider {
|
||||
func getPreviewCommitType(forViewController viewController: UIViewController) -> PreviewCommitType {
|
||||
return viewController is LargeImageViewController ? .modal : .nav
|
||||
}
|
||||
}
|
||||
|
||||
@objc extension UITableViewController: UIViewControllerPreviewingDelegate {
|
||||
public func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
|
||||
if let indexPath = tableView.indexPathForRow(at: location),
|
||||
let cell = tableView.cellForRow(at: indexPath) as? UITableViewCell & PreviewViewControllerProvider {
|
||||
let cellLocation = cell.convert(location, from: tableView)
|
||||
if let vc = cell.getPreviewViewController(forLocation: cellLocation, sourceViewController: self) {
|
||||
previewingContext.sourceRect = tableView.rectForRow(at: indexPath)
|
||||
return vc
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
public func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
|
||||
if viewControllerToCommit is LargeImageViewController {
|
||||
present(viewControllerToCommit, animated: false)
|
||||
} else {
|
||||
navigationController!.pushViewController(viewControllerToCommit, animated: false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//class PreviewingController: NSObject, UIViewControllerPreviewingDelegate {
|
||||
//
|
||||
// var currentCommitType: PreviewCommitType?
|
||||
// var owner: UIViewController?
|
||||
//
|
||||
// init(owner: UIViewController) {
|
||||
// self.owner = owner
|
||||
// }
|
||||
//
|
||||
// func previewingContext(_ previewingContext: UIViewControllerPreviewing, viewControllerForLocation location: CGPoint) -> UIViewController? {
|
||||
// if let owner = owner as? UITableViewController,
|
||||
// let indexPath = owner.tableView.indexPathForRow(at: location),
|
||||
// let cell = owner.tableView.cellForRow(at: indexPath) as? UITableViewCell & PreviewViewControllerProvider {
|
||||
// let cellLocation = cell.convert(location, from: owner.tableView)
|
||||
// if let vc = cell.getPreviewViewController(forLocation: cellLocation, sourceViewController: owner) {
|
||||
// currentCommitType = cell.getPreviewCommitType(forViewController: vc)
|
||||
// previewingContext.sourceRect = owner.tableView.rectForRow(at: indexPath)
|
||||
// return vc
|
||||
// }
|
||||
// }
|
||||
// return nil
|
||||
// }
|
||||
//
|
||||
// func previewingContext(_ previewingContext: UIViewControllerPreviewing, commit viewControllerToCommit: UIViewController) {
|
||||
// switch currentCommitType ?? .nav {
|
||||
// case .modal:
|
||||
// owner?.present(viewControllerToCommit, animated: false)
|
||||
// case .nav:
|
||||
// owner?.navigationController!.pushViewController(viewControllerToCommit, animated: false)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//}
|
|
@ -0,0 +1,15 @@
|
|||
//
|
||||
// PreviewingController.swift
|
||||
// Tusker
|
||||
//
|
||||
// Created by Shadowfacts on 10/11/18.
|
||||
// Copyright © 2018 Shadowfacts. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class PreviewingController {
|
||||
|
||||
var currentCommitType: PreviewCommitType
|
||||
|
||||
}
|
|
@ -11,18 +11,30 @@ import SafariServices
|
|||
import Pachyderm
|
||||
|
||||
protocol TuskerNavigationDelegate {
|
||||
func viewController(forAccount accountID: String) -> UIViewController
|
||||
|
||||
func selected(account accountID: String)
|
||||
|
||||
func viewController(forMention mention: Mention) -> UIViewController
|
||||
|
||||
func selected(mention: Mention)
|
||||
|
||||
func viewController(forTag tag: Hashtag) -> UIViewController
|
||||
|
||||
func selected(tag: Hashtag)
|
||||
|
||||
func viewController(forURL url: URL) -> UIViewController
|
||||
|
||||
func selected(url: URL)
|
||||
|
||||
func viewController(forStatus statusID: String) -> UIViewController
|
||||
|
||||
func selected(status statusID: String)
|
||||
|
||||
func reply(to statusID: String)
|
||||
|
||||
func viewController(forImage image: UIImage, description: String?, animatingFrom originView: UIView) -> UIViewController
|
||||
|
||||
func showLargeImage(_ image: UIImage, description: String?, animatingFrom originView: UIView)
|
||||
|
||||
func showMoreOptions(forStatus statusID: String)
|
||||
|
@ -30,6 +42,10 @@ protocol TuskerNavigationDelegate {
|
|||
|
||||
extension TuskerNavigationDelegate where Self: UIViewController {
|
||||
|
||||
func viewController(forAccount accountID: String) -> UIViewController {
|
||||
return ProfileTableViewController.create(for: accountID)
|
||||
}
|
||||
|
||||
func selected(account accountID: String) {
|
||||
// don't open if the account is the same as the current one
|
||||
if let profileController = self as? ProfileTableViewController,
|
||||
|
@ -40,32 +56,48 @@ extension TuskerNavigationDelegate where Self: UIViewController {
|
|||
guard let navigationController = navigationController else {
|
||||
fatalError("Can't show profile VC when not in navigation controller")
|
||||
}
|
||||
let vc = ProfileTableViewController.create(for: accountID)
|
||||
let vc = viewController(forAccount: accountID)
|
||||
navigationController.pushViewController(vc, animated: true)
|
||||
}
|
||||
|
||||
func viewController(forMention mention: Mention) -> UIViewController {
|
||||
return ProfileTableViewController.create(for: mention.id)
|
||||
}
|
||||
|
||||
func selected(mention: Mention) {
|
||||
guard let navigationController = navigationController else {
|
||||
fatalError("Can't show profile VC from mention when not in navigation controller")
|
||||
}
|
||||
let vc = ProfileTableViewController.create(for: mention.id)
|
||||
let vc = viewController(forMention: mention)
|
||||
navigationController.pushViewController(vc, animated: true)
|
||||
}
|
||||
|
||||
func viewController(forTag tag: Hashtag) -> UIViewController {
|
||||
let timeline = Timeline.tag(hashtag: tag.name)
|
||||
return TimelineTableViewController.create(for: timeline)
|
||||
}
|
||||
|
||||
func selected(tag: Hashtag) {
|
||||
guard let navigationController = navigationController else {
|
||||
fatalError("Can't show hashtag timeline when not in navigation controller")
|
||||
}
|
||||
let timeline = Timeline.tag(hashtag: tag.name)
|
||||
let vc = TimelineTableViewController.create(for: timeline)
|
||||
let vc = viewController(forTag: tag)
|
||||
navigationController.pushViewController(vc, animated: true)
|
||||
}
|
||||
|
||||
func viewController(forURL url: URL) -> UIViewController {
|
||||
return SFSafariViewController(url: url)
|
||||
}
|
||||
|
||||
func selected(url: URL) {
|
||||
let vc = SFSafariViewController(url: url)
|
||||
let vc = viewController(forURL: url)
|
||||
present(vc, animated: true)
|
||||
}
|
||||
|
||||
func viewController(forStatus statusID: String) -> UIViewController {
|
||||
return ConversationViewController.create(for: statusID)
|
||||
}
|
||||
|
||||
func selected(status statusID: String) {
|
||||
// don't open if the conversation is the same as the current one
|
||||
if let conversationController = self as? ConversationViewController,
|
||||
|
@ -76,7 +108,7 @@ extension TuskerNavigationDelegate where Self: UIViewController {
|
|||
guard let navigationController = navigationController else {
|
||||
fatalError("Can't show conversation VC when not in navigation controller")
|
||||
}
|
||||
let vc = ConversationViewController.create(for: statusID)
|
||||
let vc = viewController(forStatus: statusID)
|
||||
navigationController.pushViewController(vc, animated: true)
|
||||
}
|
||||
|
||||
|
@ -85,22 +117,17 @@ extension TuskerNavigationDelegate where Self: UIViewController {
|
|||
present(vc, animated: true)
|
||||
}
|
||||
|
||||
func showLargeImage(_ image: UIImage, description: String?, animatingFrom originView: UIView) {
|
||||
guard let self = self as? UIViewController & LargeImageViewControllerDelegate else { return }
|
||||
let vc = LargeImageViewController.create(image: image, description: description)
|
||||
vc.delegate = self
|
||||
var frame = originView.convert(originView.bounds, to: view)
|
||||
if let scrollView = view as? UIScrollView {
|
||||
let scale = scrollView.zoomScale
|
||||
let width = frame.width * scale
|
||||
let height = frame.height * scale
|
||||
let x = frame.minX * scale - scrollView.contentOffset.x + scrollView.frame.minX
|
||||
let y = frame.minY * scale - scrollView.contentOffset.y + scrollView.frame.minY
|
||||
frame = CGRect(x: x, y: y, width: width, height: height)
|
||||
func viewController(forImage image: UIImage, description: String?, animatingFrom originView: UIView) -> UIViewController {
|
||||
guard let self = self as? UIViewController & LargeImageViewControllerDelegate else {
|
||||
fatalError("Can't create large image view controller unless self is LargeImageViewControllerDelegate")
|
||||
}
|
||||
vc.originFrame = frame
|
||||
vc.originCornerRadius = originView.layer.cornerRadius
|
||||
vc.transitioningDelegate = self
|
||||
let vc = LargeImageViewController.create(image: image, description: description, sourceView: originView, sourceViewController: self)
|
||||
vc.delegate = self
|
||||
return vc
|
||||
}
|
||||
|
||||
func showLargeImage(_ image: UIImage, description: String?, animatingFrom originView: UIView) {
|
||||
let vc = viewController(forImage: image, description: description, animatingFrom: originView)
|
||||
present(vc, animated: true)
|
||||
}
|
||||
|
||||
|
|
|
@ -11,17 +11,9 @@ import TTTAttributedLabel
|
|||
import Pachyderm
|
||||
import SwiftSoup
|
||||
|
||||
protocol ContentLabelNavigationDelegate {
|
||||
func selected(mention: Mention)
|
||||
|
||||
func selected(tag: Hashtag)
|
||||
|
||||
func selected(url: URL)
|
||||
}
|
||||
|
||||
class ContentLabel: TTTAttributedLabel {
|
||||
|
||||
var navigationDelegate: ContentLabelNavigationDelegate?
|
||||
var navigationDelegate: TuskerNavigationDelegate?
|
||||
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
|
@ -92,10 +84,28 @@ class ContentLabel: TTTAttributedLabel {
|
|||
}
|
||||
}
|
||||
|
||||
func getViewController(forLinkAt point: CGPoint) -> UIViewController? {
|
||||
guard let navigationDelegate = navigationDelegate,
|
||||
let link = link(at: point),
|
||||
let url = link.result.url else {
|
||||
return nil
|
||||
}
|
||||
let text = (self.text as! NSString).substring(with: link.result.range)
|
||||
if let mention = getMention(for: url, text: text) {
|
||||
return navigationDelegate.viewController(forMention: mention)
|
||||
} else if let tag = getHashtag(for: url, text: text) {
|
||||
return navigationDelegate.viewController(forTag: tag)
|
||||
} else {
|
||||
return navigationDelegate.viewController(forURL: url)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Interaction
|
||||
func linkTapped(_ label: TTTAttributedLabel!, _ link: TTTAttributedLabelLink!) {
|
||||
if let navigationDelegate = navigationDelegate,
|
||||
let url = link.result.url {
|
||||
guard let navigationDelegate = navigationDelegate,
|
||||
let url = link.result.url else {
|
||||
return
|
||||
}
|
||||
let text = (self.text as! NSString).substring(with: link.result.range)
|
||||
if let mention = getMention(for: url, text: text) {
|
||||
navigationDelegate.selected(mention: mention)
|
||||
|
@ -105,7 +115,6 @@ class ContentLabel: TTTAttributedLabel {
|
|||
navigationDelegate.selected(url: url)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func linkLongPressed(_ label: TTTAttributedLabel!, _ link: TTTAttributedLabelLink!) {
|
||||
// todo: long press options
|
||||
|
|
|
@ -11,11 +11,16 @@ import Pachyderm
|
|||
|
||||
class ActionNotificationTableViewCell: UITableViewCell, PreferencesAdaptive {
|
||||
|
||||
var delegate: StatusTableViewCellDelegate?
|
||||
var delegate: StatusTableViewCellDelegate? {
|
||||
didSet {
|
||||
contentLabel.navigationDelegate = delegate
|
||||
}
|
||||
}
|
||||
|
||||
@IBOutlet weak var displayNameLabel: UILabel!
|
||||
@IBOutlet weak var usernameLabel: UILabel!
|
||||
@IBOutlet weak var contentLabel: StatusContentLabel!
|
||||
@IBOutlet weak var avatarContainerView: UIView!
|
||||
@IBOutlet weak var opAvatarImageView: UIImageView!
|
||||
@IBOutlet weak var actionAvatarImageView: UIImageView!
|
||||
@IBOutlet weak var actionLabel: UILabel!
|
||||
|
@ -40,7 +45,6 @@ class ActionNotificationTableViewCell: UITableViewCell, PreferencesAdaptive {
|
|||
actionAvatarImageView.layer.masksToBounds = true
|
||||
actionLabel.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(actionPressed)))
|
||||
actionLabel.isUserInteractionEnabled = true
|
||||
contentLabel.navigationDelegate = self
|
||||
}
|
||||
|
||||
func updateUIForPreferences() {
|
||||
|
@ -186,16 +190,14 @@ class ActionNotificationTableViewCell: UITableViewCell, PreferencesAdaptive {
|
|||
|
||||
}
|
||||
|
||||
extension ActionNotificationTableViewCell: ContentLabelNavigationDelegate {
|
||||
func selected(mention: Mention) {
|
||||
delegate?.selected(mention: mention)
|
||||
extension ActionNotificationTableViewCell: PreviewViewControllerProvider {
|
||||
func getPreviewViewController(forLocation location: CGPoint, sourceViewController: UIViewController) -> UIViewController? {
|
||||
if avatarContainerView.frame.contains(location) {
|
||||
return delegate?.viewController(forAccount: notification.account.id)
|
||||
} else if contentLabel.frame.contains(location),
|
||||
let vc = contentLabel.getViewController(forLinkAt: contentLabel.convert(location, from: self)) {
|
||||
return vc
|
||||
}
|
||||
|
||||
func selected(tag: Hashtag) {
|
||||
delegate?.selected(tag: tag)
|
||||
}
|
||||
|
||||
func selected(url: URL) {
|
||||
delegate?.selected(url: url)
|
||||
return delegate?.viewController(forStatus: statusID)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.15" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.23.1" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.9"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.16.1"/>
|
||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
|
@ -124,6 +124,7 @@
|
|||
<outlet property="actionAvatarImageView" destination="bXi-tl-kR9" id="QB8-ll-vNb"/>
|
||||
<outlet property="actionLabel" destination="Cwu-6F-uNO" id="d7e-Za-Xed"/>
|
||||
<outlet property="attachmentsView" destination="HGa-49-qx0" id="x7p-uh-QRj"/>
|
||||
<outlet property="avatarContainerView" destination="RTx-MR-PMy" id="Qri-Cd-kjN"/>
|
||||
<outlet property="contentLabel" destination="30l-QK-uJH" id="eNc-Xt-C0E"/>
|
||||
<outlet property="displayNameLabel" destination="wFQ-nU-BGD" id="MkH-di-Bgr"/>
|
||||
<outlet property="opAvatarImageView" destination="BE8-ts-R0p" id="cu8-Kt-rbM"/>
|
||||
|
|
|
@ -96,3 +96,9 @@ class FollowNotificationTableViewCell: UITableViewCell, PreferencesAdaptive {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
extension FollowNotificationTableViewCell: PreviewViewControllerProvider {
|
||||
func getPreviewViewController(forLocation location: CGPoint, sourceViewController: UIViewController) -> UIViewController? {
|
||||
return delegate?.viewController(forAccount: accountID)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,7 +15,11 @@ protocol ProfileHeaderTableViewCellDelegate: TuskerNavigationDelegate {
|
|||
|
||||
class ProfileHeaderTableViewCell: UITableViewCell, PreferencesAdaptive {
|
||||
|
||||
var delegate: ProfileHeaderTableViewCellDelegate?
|
||||
var delegate: ProfileHeaderTableViewCellDelegate? {
|
||||
didSet {
|
||||
noteLabel.navigationDelegate = delegate
|
||||
}
|
||||
}
|
||||
|
||||
@IBOutlet weak var headerImageView: UIImageView!
|
||||
@IBOutlet weak var avatarContainerView: UIView!
|
||||
|
@ -37,7 +41,6 @@ class ProfileHeaderTableViewCell: UITableViewCell, PreferencesAdaptive {
|
|||
avatarImageView.isUserInteractionEnabled = true
|
||||
headerImageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(headerPressed)))
|
||||
headerImageView.isUserInteractionEnabled = true
|
||||
noteLabel.navigationDelegate = self
|
||||
}
|
||||
|
||||
func updateUIForPreferences() {
|
||||
|
@ -109,17 +112,3 @@ class ProfileHeaderTableViewCell: UITableViewCell, PreferencesAdaptive {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
extension ProfileHeaderTableViewCell: ContentLabelNavigationDelegate {
|
||||
func selected(mention: Mention) {
|
||||
delegate?.selected(mention: mention)
|
||||
}
|
||||
|
||||
func selected(tag: Hashtag) {
|
||||
delegate?.selected(tag: tag)
|
||||
}
|
||||
|
||||
func selected(url: URL) {
|
||||
delegate?.selected(url: url)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,11 @@ import Pachyderm
|
|||
|
||||
class ConversationMainStatusTableViewCell: UITableViewCell, PreferencesAdaptive {
|
||||
|
||||
var delegate: StatusTableViewCellDelegate?
|
||||
var delegate: StatusTableViewCellDelegate? {
|
||||
didSet {
|
||||
contentLabel.navigationDelegate = delegate
|
||||
}
|
||||
}
|
||||
|
||||
@IBOutlet weak var displayNameLabel: UILabel!
|
||||
@IBOutlet weak var usernameLabel: UILabel!
|
||||
|
@ -49,7 +53,6 @@ class ConversationMainStatusTableViewCell: UITableViewCell, PreferencesAdaptive
|
|||
avatarImageView.layer.masksToBounds = true
|
||||
attachmentsView.layer.cornerRadius = 5
|
||||
attachmentsView.layer.masksToBounds = true
|
||||
contentLabel.navigationDelegate = self
|
||||
}
|
||||
|
||||
func updateUIForPreferences() {
|
||||
|
@ -216,22 +219,27 @@ class ConversationMainStatusTableViewCell: UITableViewCell, PreferencesAdaptive
|
|||
|
||||
}
|
||||
|
||||
extension ConversationMainStatusTableViewCell: ContentLabelNavigationDelegate {
|
||||
func selected(mention: Mention) {
|
||||
delegate?.selected(mention: mention)
|
||||
}
|
||||
|
||||
func selected(tag: Hashtag) {
|
||||
delegate?.selected(tag: tag)
|
||||
}
|
||||
|
||||
func selected(url: URL) {
|
||||
delegate?.selected(url: url)
|
||||
}
|
||||
}
|
||||
|
||||
extension ConversationMainStatusTableViewCell: AttachmentViewDelegate {
|
||||
func showLargeAttachment(for attachmentView: AttachmentView) {
|
||||
delegate?.showLargeImage(attachmentView.image!, description: attachmentView.attachment.description, animatingFrom: attachmentView)
|
||||
}
|
||||
}
|
||||
|
||||
extension ConversationMainStatusTableViewCell: PreviewViewControllerProvider {
|
||||
func getPreviewViewController(forLocation location: CGPoint, sourceViewController: UIViewController) -> UIViewController? {
|
||||
if avatarImageView.frame.contains(location) {
|
||||
return delegate?.viewController(forAccount: accountID)
|
||||
} else if attachmentsView.frame.contains(location) {
|
||||
let attachmentsViewLocation = attachmentsView.convert(location, from: self)
|
||||
if let attachmentView = attachmentsView.subviews.first(where: { $0.frame.contains(attachmentsViewLocation) }) as? AttachmentView {
|
||||
let image = attachmentView.image!
|
||||
let description = attachmentView.description
|
||||
return delegate?.viewController(forImage: image, description: description, animatingFrom: attachmentView)
|
||||
}
|
||||
} else if contentLabel.frame.contains(location),
|
||||
let vc = contentLabel.getViewController(forLinkAt: contentLabel.convert(location, from: self)) {
|
||||
return vc
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,11 @@ protocol StatusTableViewCellDelegate: TuskerNavigationDelegate {
|
|||
|
||||
class StatusTableViewCell: UITableViewCell, PreferencesAdaptive {
|
||||
|
||||
var delegate: StatusTableViewCellDelegate?
|
||||
var delegate: StatusTableViewCellDelegate? {
|
||||
didSet {
|
||||
contentLabel.navigationDelegate = delegate
|
||||
}
|
||||
}
|
||||
|
||||
@IBOutlet weak var displayNameLabel: UILabel!
|
||||
@IBOutlet weak var usernameLabel: UILabel!
|
||||
|
@ -57,7 +61,6 @@ class StatusTableViewCell: UITableViewCell, PreferencesAdaptive {
|
|||
avatarImageView.layer.masksToBounds = true
|
||||
attachmentsView.layer.cornerRadius = 5
|
||||
attachmentsView.layer.masksToBounds = true
|
||||
contentLabel.navigationDelegate = self
|
||||
}
|
||||
|
||||
func updateUIForPreferences() {
|
||||
|
@ -345,22 +348,27 @@ extension StatusTableViewCell: TableViewSwipeActionProvider {
|
|||
|
||||
}
|
||||
|
||||
extension StatusTableViewCell: ContentLabelNavigationDelegate {
|
||||
func selected(mention: Mention) {
|
||||
delegate?.selected(mention: mention)
|
||||
}
|
||||
|
||||
func selected(tag: Hashtag) {
|
||||
delegate?.selected(tag: tag)
|
||||
}
|
||||
|
||||
func selected(url: URL) {
|
||||
delegate?.selected(url: url)
|
||||
}
|
||||
}
|
||||
|
||||
extension StatusTableViewCell: AttachmentViewDelegate {
|
||||
func showLargeAttachment(for attachmentView: AttachmentView) {
|
||||
delegate?.showLargeImage(attachmentView.image!, description: attachmentView.attachment.description, animatingFrom: attachmentView)
|
||||
}
|
||||
}
|
||||
|
||||
extension StatusTableViewCell: PreviewViewControllerProvider {
|
||||
func getPreviewViewController(forLocation location: CGPoint, sourceViewController: UIViewController) -> UIViewController? {
|
||||
if avatarImageView.frame.contains(location) {
|
||||
return delegate?.viewController(forAccount: accountID)
|
||||
} else if attachmentsView.frame.contains(location) {
|
||||
let attachmentsViewLocation = attachmentsView.convert(location, from: self)
|
||||
if let attachmentView = attachmentsView.subviews.first(where: { $0.frame.contains(attachmentsViewLocation) }) as? AttachmentView {
|
||||
let image = attachmentView.image!
|
||||
let description = attachmentView.attachment.description
|
||||
return delegate?.viewController(forImage: image, description: description, animatingFrom: attachmentView)
|
||||
}
|
||||
} else if contentLabel.frame.contains(location),
|
||||
let vc = contentLabel.getViewController(forLinkAt: contentLabel.convert(location, from: self)) {
|
||||
return vc
|
||||
}
|
||||
return delegate?.viewController(forStatus: statusID)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue