Fix crash when tapping more actions buttons on iPad

Fixes #78
This commit is contained in:
Shadowfacts 2020-01-17 21:29:53 -05:00
parent 53702a8324
commit 8178a1f339
Signed by: shadowfacts
GPG Key ID: 94A5AB95422746E5
8 changed files with 48 additions and 35 deletions

View File

@ -261,7 +261,7 @@ extension ProfileTableViewController: StatusTableViewCellDelegate {
}
extension ProfileTableViewController: ProfileHeaderTableViewCellDelegate {
func showMoreOptions() {
func showMoreOptions(cell: ProfileHeaderTableViewCell) {
let account = MastodonCache.account(for: accountID)!
MastodonCache.relationship(for: account.id) { [weak self] (relationship) in
@ -276,6 +276,7 @@ extension ProfileTableViewController: ProfileHeaderTableViewCellDelegate {
DispatchQueue.main.async {
let activityController = UIActivityViewController(activityItems: [account.url, account], applicationActivities: customActivities)
activityController.completionWithItemsHandler = OpenInSafariActivity.completionHandler(viewController: self, url: account.url)
activityController.popoverPresentationController?.sourceView = cell.moreButtonVisualEffectView
self.present(activityController, animated: true)
}
}

View File

@ -22,7 +22,7 @@ protocol MenuPreviewProvider {
extension MenuPreviewProvider {
func actionsForProfile(accountID: String) -> [UIAction] {
func actionsForProfile(accountID: String, sourceView: UIView?) -> [UIAction] {
guard let account = MastodonCache.account(for: accountID) else { return [] }
return [
createAction(identifier: "openinsafari", title: "Open in Safari", systemImageName: "safari", handler: { (_) in
@ -32,27 +32,27 @@ extension MenuPreviewProvider {
self.navigationDelegate?.compose(mentioning: account.acct)
}),
createAction(identifier: "share", title: "Share...", systemImageName: "square.and.arrow.up", handler: { (_) in
self.navigationDelegate?.showMoreOptions(forAccount: accountID)
self.navigationDelegate?.showMoreOptions(forAccount: accountID, sourceView: sourceView)
})
]
}
func actionsForURL(_ url: URL) -> [UIAction] {
func actionsForURL(_ url: URL, sourceView: UIView?) -> [UIAction] {
return [
createAction(identifier: "openinsafari", title: "Open in Safari", systemImageName: "safari", handler: { (_) in
self.navigationDelegate?.selected(url: url)
}),
createAction(identifier: "share", title: "Share...", systemImageName: "square.and.arrow.up", handler: { (_) in
self.navigationDelegate?.showMoreOptions(forURL: url)
self.navigationDelegate?.showMoreOptions(forURL: url, sourceView: sourceView)
})
]
}
func actionsForHashtag(_ hashtag: Hashtag) -> [UIAction] {
return actionsForURL(hashtag.url)
func actionsForHashtag(_ hashtag: Hashtag, sourceView: UIView?) -> [UIAction] {
return actionsForURL(hashtag.url, sourceView: sourceView)
}
func actionsForStatus(statusID: String) -> [UIAction] {
func actionsForStatus(statusID: String, sourceView: UIView?) -> [UIAction] {
guard let status = MastodonCache.status(for: statusID) else { return [] }
return [
createAction(identifier: "reply", title: "Reply", systemImageName: "arrowshape.turn.up.left", handler: { (_) in
@ -62,7 +62,7 @@ extension MenuPreviewProvider {
self.navigationDelegate?.selected(url: status.url!)
}),
createAction(identifier: "share", title: "Share...", systemImageName: "square.and.arrow.up", handler: { (_) in
self.navigationDelegate?.showMoreOptions(forStatus: statusID)
self.navigationDelegate?.showMoreOptions(forStatus: statusID, sourceView: sourceView)
})
]
}

View File

@ -44,11 +44,11 @@ protocol TuskerNavigationDelegate {
func showGallery(attachments: [Attachment], sourceViews: [UIImageView?], startIndex: Int)
func showMoreOptions(forStatus statusID: String)
func showMoreOptions(forStatus statusID: String, sourceView: UIView?)
func showMoreOptions(forAccount accountID: String)
func showMoreOptions(forAccount accountID: String, sourceView: UIView?)
func showMoreOptions(forURL url: URL)
func showMoreOptions(forURL url: URL, sourceView: UIView?)
func showFollowedByList(accountIDs: [String])
@ -182,7 +182,7 @@ extension TuskerNavigationDelegate where Self: UIViewController {
present(gallery(attachments: attachments, sourceViews: sourceViews, startIndex: startIndex), animated: true)
}
private func moreOptions(forURL url: URL) -> UIViewController {
private func moreOptions(forURL url: URL) -> UIActivityViewController {
let customActivites: [UIActivity] = [
OpenInSafariActivity()
]
@ -191,7 +191,7 @@ extension TuskerNavigationDelegate where Self: UIViewController {
return activityController
}
private func moreOptions(forStatus statusID: String) -> UIViewController {
private func moreOptions(forStatus statusID: String) -> UIActivityViewController {
guard let status = MastodonCache.status(for: statusID) else { fatalError("Missing cached status \(statusID)") }
guard let url = status.url else { fatalError("Missing url for status \(statusID)") }
var customActivites: [UIActivity] = [OpenInSafariActivity()]
@ -210,21 +210,27 @@ extension TuskerNavigationDelegate where Self: UIViewController {
return activityController
}
private func moreOptions(forAccount accountID: String) -> UIViewController {
private func moreOptions(forAccount accountID: String) -> UIActivityViewController {
guard let account = MastodonCache.account(for: accountID) else { fatalError("Missing cached account \(accountID)") }
return moreOptions(forURL: account.url)
}
func showMoreOptions(forStatus statusID: String) {
present(moreOptions(forStatus: statusID), animated: true)
func showMoreOptions(forStatus statusID: String, sourceView: UIView?) {
let vc = moreOptions(forStatus: statusID)
vc.popoverPresentationController?.sourceView = sourceView
present(vc, animated: true)
}
func showMoreOptions(forURL url: URL) {
present(moreOptions(forURL: url), animated: true)
func showMoreOptions(forURL url: URL, sourceView: UIView?) {
let vc = moreOptions(forURL: url)
vc.popoverPresentationController?.sourceView = sourceView
present(vc, animated: true)
}
func showMoreOptions(forAccount accountID: String) {
present(moreOptions(forAccount: accountID), animated: true)
func showMoreOptions(forAccount accountID: String, sourceView: UIView?) {
let vc = moreOptions(forAccount: accountID)
vc.popoverPresentationController?.sourceView = sourceView
present(vc, animated: true)
}
func showFollowedByList(accountIDs: [String]) {

View File

@ -68,6 +68,9 @@ extension AccountTableViewCell: MenuPreviewProvider {
var navigationDelegate: TuskerNavigationDelegate? { return delegate }
func getPreviewProviders(for location: CGPoint, sourceViewController: UIViewController) -> PreviewProviders? {
return (content: { ProfileTableViewController(accountID: self.accountID) }, actions: { self.actionsForProfile(accountID: self.accountID) })
return (
content: { ProfileTableViewController(accountID: self.accountID) },
actions: { self.actionsForProfile(accountID: self.accountID, sourceView: self.avatarImageView) }
)
}
}

View File

@ -209,7 +209,7 @@ class ContentLabel: LinkLabel {
}
override func linkLongPressed(_ link: LinkLabel.Link) {
navigationDelegate?.showMoreOptions(forURL: link.url)
navigationDelegate?.showMoreOptions(forURL: link.url, sourceView: self)
}
// MARK: - Navigation

View File

@ -10,7 +10,7 @@ import UIKit
import Pachyderm
protocol ProfileHeaderTableViewCellDelegate: TuskerNavigationDelegate {
func showMoreOptions()
func showMoreOptions(cell: ProfileHeaderTableViewCell)
}
class ProfileHeaderTableViewCell: UITableViewCell {
@ -137,7 +137,7 @@ class ProfileHeaderTableViewCell: UITableViewCell {
}
@objc func morePressed() {
delegate?.showMoreOptions()
delegate?.showMoreOptions(cell: self)
}
@objc func avatarPressed() {
@ -161,11 +161,11 @@ extension ProfileHeaderTableViewCell: MenuPreviewProvider {
actions: {
let text = (self.noteLabel.text! as NSString).substring(with: link.range)
if let mention = self.noteLabel.getMention(for: link.url, text: text) {
return self.actionsForProfile(accountID: mention.id)
return self.actionsForProfile(accountID: mention.id, sourceView: self)
} else if let hashtag = self.noteLabel.getHashtag(for: link.url, text: text) {
return self.actionsForHashtag(hashtag)
return self.actionsForHashtag(hashtag, sourceView: self)
} else {
return self.actionsForURL(link.url)
return self.actionsForURL(link.url, sourceView: self)
}
}
)

View File

@ -289,7 +289,7 @@ class BaseStatusTableViewCell: UITableViewCell {
}
@IBAction func morePressed() {
delegate?.showMoreOptions(forStatus: statusID)
delegate?.showMoreOptions(forStatus: statusID, sourceView: moreButton)
}
@objc func accountPressed() {
@ -314,7 +314,10 @@ extension BaseStatusTableViewCell: MenuPreviewProvider {
func getPreviewProviders(for location: CGPoint, sourceViewController: UIViewController) -> PreviewProviders? {
if avatarImageView.frame.contains(location) {
return (content: { ProfileTableViewController(accountID: self.accountID)}, actions: { self.actionsForProfile(accountID: self.accountID) })
return (
content: { ProfileTableViewController(accountID: self.accountID)},
actions: { self.actionsForProfile(accountID: self.accountID, sourceView: self.avatarImageView) }
)
} else if attachmentsView.frame.contains(location) {
let attachmentsViewLocation = attachmentsView.convert(location, from: self)
if let attachmentView = attachmentsView.attachmentViews.allObjects.first(where: { $0.frame.contains(attachmentsViewLocation) }),
@ -329,11 +332,11 @@ extension BaseStatusTableViewCell: MenuPreviewProvider {
actions: {
let text = (self.contentLabel.text! as NSString).substring(with: link.range)
if let mention = self.contentLabel.getMention(for: link.url, text: text) {
return self.actionsForProfile(accountID: mention.id)
return self.actionsForProfile(accountID: mention.id, sourceView: self)
} else if let hashtag = self.contentLabel.getHashtag(for: link.url, text: text) {
return self.actionsForHashtag(hashtag)
return self.actionsForHashtag(hashtag, sourceView: self)
} else {
return self.actionsForURL(link.url)
return self.actionsForURL(link.url, sourceView: self)
}
}
)

View File

@ -127,7 +127,7 @@ class TimelineStatusTableViewCell: BaseStatusTableViewCell {
override func getStatusCellPreviewProviders(for location: CGPoint, sourceViewController: UIViewController) -> BaseStatusTableViewCell.PreviewProviders? {
return (
content: { ConversationTableViewController(for: self.statusID, state: self.statusState.copy()) },
actions: { self.actionsForStatus(statusID: self.statusID) }
actions: { self.actionsForStatus(statusID: self.statusID, sourceView: self) }
)
}
@ -211,7 +211,7 @@ extension TimelineStatusTableViewCell: TableViewSwipeActionProvider {
reply.backgroundColor = tintColor
let more = UIContextualAction(style: .normal, title: "More") { (action, view, completion) in
completion(true)
self.delegate?.showMoreOptions(forStatus: self.statusID)
self.delegate?.showMoreOptions(forStatus: self.statusID, sourceView: self)
}
more.image = UIImage(systemName: "ellipsis")
more.backgroundColor = .gray