From 74ff765bb45fdbec03b6af19bcd7b11d0d238122 Mon Sep 17 00:00:00 2001 From: Ryan Nystrom Date: Fri, 23 Jun 2017 14:32:38 -0400 Subject: [PATCH] tapping links in md opens safari --- .../IssueCommentSectionController.swift | 23 ++++++-- .../Markdown/MMElement+Attributes.swift | 4 +- .../Quotes/IssueCommentQuoteCell.swift | 4 +- .../Comments/Text/IssueCommentTextCell.swift | 4 +- .../Systems/NSAttributedStringSizing.swift | 9 ++++ Classes/Views/AttributedStringView.swift | 54 +++++++++++++++++++ .../UIView+NSAttributedStringSizing.swift | 22 -------- Freetime.xcodeproj/project.pbxproj | 10 ++-- 8 files changed, 93 insertions(+), 37 deletions(-) create mode 100644 Classes/Views/AttributedStringView.swift delete mode 100644 Classes/Views/UIView+NSAttributedStringSizing.swift diff --git a/Classes/Issues/Comments/IssueCommentSectionController.swift b/Classes/Issues/Comments/IssueCommentSectionController.swift index ea2c28e7..e46bc0e1 100644 --- a/Classes/Issues/Comments/IssueCommentSectionController.swift +++ b/Classes/Issues/Comments/IssueCommentSectionController.swift @@ -18,7 +18,8 @@ final class IssueCommentSectionController: ListBindingSectionController [String: Any]? { + var fractionDistance: CGFloat = 1.0 + let index = layoutManager.characterIndex(for: point, in: textContainer, fractionOfDistanceBetweenInsertionPoints: &fractionDistance) + if index != NSNotFound, fractionDistance < 1.0 { + return attributedText.attributes(at: index, effectiveRange: nil) + } + return nil + } + // MARK: ListDiffable func diffIdentifier() -> NSObjectProtocol { diff --git a/Classes/Views/AttributedStringView.swift b/Classes/Views/AttributedStringView.swift new file mode 100644 index 00000000..f822dd01 --- /dev/null +++ b/Classes/Views/AttributedStringView.swift @@ -0,0 +1,54 @@ +// +// AttributedStringView.swift +// Freetime +// +// Created by Ryan Nystrom on 6/23/17. +// Copyright © 2017 Ryan Nystrom. All rights reserved. +// + +import UIKit + +protocol AttributedStringViewDelegate: class { + func didTapURL(view: AttributedStringView, url: URL) +} + +final class AttributedStringView: UIView { + + var delegate: AttributedStringViewDelegate? = nil + + private var text: NSAttributedStringSizing? = nil + + override init(frame: CGRect) { + super.init(frame: frame) + + backgroundColor = .white + isOpaque = true + layer.contentsGravity = kCAGravityTopLeft + + let tap = UITapGestureRecognizer(target: self, action: #selector(AttributedStringView.onTap(recognizer:))) + addGestureRecognizer(tap) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: Public API + + func configureAndSizeToFit(text: NSAttributedStringSizing) { + self.text = text + layer.contentsScale = text.screenScale + layer.contents = text.contents() + frame = UIEdgeInsetsInsetRect(CGRect(origin: .zero, size: text.textViewSize), text.inset) + } + + // MARK: Private API + + func onTap(recognizer: UITapGestureRecognizer) { + guard let urlString = text?.attributes(point: recognizer.location(in: self))?[MarkdownURLName] as? String, + let url = URL(string: urlString) + else { return } + delegate?.didTapURL(view: self, url: url) + } + +} diff --git a/Classes/Views/UIView+NSAttributedStringSizing.swift b/Classes/Views/UIView+NSAttributedStringSizing.swift deleted file mode 100644 index 6b2ded28..00000000 --- a/Classes/Views/UIView+NSAttributedStringSizing.swift +++ /dev/null @@ -1,22 +0,0 @@ -// -// UIView+NSAttributedStringSizing.swift -// Freetime -// -// Created by Ryan Nystrom on 6/9/17. -// Copyright © 2017 Ryan Nystrom. All rights reserved. -// - -import UIKit - -extension UIView { - - func configureAndLayout(_ text: NSAttributedStringSizing) { - backgroundColor = .white - isOpaque = true - layer.contentsGravity = kCAGravityTopLeft - layer.contentsScale = text.screenScale - layer.contents = text.contents() - frame = UIEdgeInsetsInsetRect(CGRect(origin: .zero, size: text.textViewSize), text.inset) - } - -} diff --git a/Freetime.xcodeproj/project.pbxproj b/Freetime.xcodeproj/project.pbxproj index 3c72eb90..91b34f9f 100644 --- a/Freetime.xcodeproj/project.pbxproj +++ b/Freetime.xcodeproj/project.pbxproj @@ -202,6 +202,7 @@ 29921BCC1EF624D400C1E848 /* UIFont+MutableTraits.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29921BCB1EF624D400C1E848 /* UIFont+MutableTraits.swift */; }; 29921BCE1EF624F500C1E848 /* MMElement+Image.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29921BCD1EF624F500C1E848 /* MMElement+Image.swift */; }; 29921BD01EF6261C00C1E848 /* MMElement+CodeBlock.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29921BCF1EF6261C00C1E848 /* MMElement+CodeBlock.swift */; }; + 299E86431EFD8D8200E5FE70 /* AttributedStringView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 299E86421EFD8D8200E5FE70 /* AttributedStringView.swift */; }; 299F2A121EC3BCF0006CE9D7 /* GithubSessionManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 299F2A111EC3BCF0006CE9D7 /* GithubSessionManager.swift */; }; 29A195021EC66B8B00C3E289 /* UIColor+Hex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29A195011EC66B8B00C3E289 /* UIColor+Hex.swift */; }; 29A195041EC74C4800C3E289 /* Date+Display.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29A195031EC74C4800C3E289 /* Date+Display.swift */; }; @@ -244,8 +245,6 @@ 29C295111EC7B83200D46CD2 /* ShowMoreDetailsLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C2950F1EC7B7FF00D46CD2 /* ShowMoreDetailsLabel.swift */; }; 29C295141EC7BAFE00D46CD2 /* NotificationsRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C295121EC7B9D500D46CD2 /* NotificationsRequest.swift */; }; 29C295171EC7BCDA00D46CD2 /* NotificationsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C295151EC7BCCD00D46CD2 /* NotificationsViewController.swift */; }; - 29C76D4C1EEB46B40048B23F /* UIView+NSAttributedStringSizing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C76D4B1EEB46B40048B23F /* UIView+NSAttributedStringSizing.swift */; }; - 29C76D4D1EEB46B40048B23F /* UIView+NSAttributedStringSizing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C76D4B1EEB46B40048B23F /* UIView+NSAttributedStringSizing.swift */; }; 29C9FDCE1EC65FEE00EE3A52 /* Notification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C9FDBA1EC65FEE00EE3A52 /* Notification.swift */; }; 29C9FDCF1EC65FEE00EE3A52 /* Organization.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C9FDBB1EC65FEE00EE3A52 /* Organization.swift */; }; 29C9FDD01EC65FEE00EE3A52 /* Permission.swift in Sources */ = {isa = PBXBuildFile; fileRef = 29C9FDBC1EC65FEE00EE3A52 /* Permission.swift */; }; @@ -394,6 +393,7 @@ 29921BCB1EF624D400C1E848 /* UIFont+MutableTraits.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIFont+MutableTraits.swift"; sourceTree = ""; }; 29921BCD1EF624F500C1E848 /* MMElement+Image.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MMElement+Image.swift"; sourceTree = ""; }; 29921BCF1EF6261C00C1E848 /* MMElement+CodeBlock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "MMElement+CodeBlock.swift"; sourceTree = ""; }; + 299E86421EFD8D8200E5FE70 /* AttributedStringView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttributedStringView.swift; sourceTree = ""; }; 299F2A111EC3BCF0006CE9D7 /* GithubSessionManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GithubSessionManager.swift; sourceTree = ""; }; 29A195011EC66B8B00C3E289 /* UIColor+Hex.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIColor+Hex.swift"; sourceTree = ""; }; 29A195031EC74C4800C3E289 /* Date+Display.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Date+Display.swift"; sourceTree = ""; }; @@ -418,7 +418,6 @@ 29C2950F1EC7B7FF00D46CD2 /* ShowMoreDetailsLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShowMoreDetailsLabel.swift; sourceTree = ""; }; 29C295121EC7B9D500D46CD2 /* NotificationsRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationsRequest.swift; sourceTree = ""; }; 29C295151EC7BCCD00D46CD2 /* NotificationsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationsViewController.swift; sourceTree = ""; }; - 29C76D4B1EEB46B40048B23F /* UIView+NSAttributedStringSizing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIView+NSAttributedStringSizing.swift"; sourceTree = ""; }; 29C9FDBA1EC65FEE00EE3A52 /* Notification.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Notification.swift; sourceTree = ""; }; 29C9FDBB1EC65FEE00EE3A52 /* Organization.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Organization.swift; sourceTree = ""; }; 29C9FDBC1EC65FEE00EE3A52 /* Permission.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Permission.swift; sourceTree = ""; }; @@ -820,7 +819,7 @@ 29A195011EC66B8B00C3E289 /* UIColor+Hex.swift */, 29A4769F1ED0E6C6005D0953 /* UIColor+Overlay.swift */, 298BA08E1EC90FEE00B01946 /* UIView+BottomBorder.swift */, - 29C76D4B1EEB46B40048B23F /* UIView+NSAttributedStringSizing.swift */, + 299E86421EFD8D8200E5FE70 /* AttributedStringView.swift */, ); path = Views; sourceTree = ""; @@ -1156,7 +1155,6 @@ 29921BCA1EF6233200C1E848 /* MMElement+Attributes.swift in Sources */, 292FCB001EDFCC510026635E /* IssueCommentViewModelHeight.swift in Sources */, 29921BCC1EF624D400C1E848 /* UIFont+MutableTraits.swift in Sources */, - 29C76D4C1EEB46B40048B23F /* UIView+NSAttributedStringSizing.swift in Sources */, 292FCB181EDFCC510026635E /* IssueTitleCell.swift in Sources */, 292FCB071EDFCC510026635E /* IssueCommentReactionCell.swift in Sources */, 29316DCD1ECD31E9007CAE3F /* StatusBar.swift in Sources */, @@ -1164,6 +1162,7 @@ 293B58531EF808DA001D067D /* IssueCommentUnsupportedModel.swift in Sources */, 294563EA1EE4EEF000DBCD35 /* IssueStatusCell.swift in Sources */, 2949674C1EF9716400B1CF1A /* IssueCommentHrModel.swift in Sources */, + 299E86431EFD8D8200E5FE70 /* AttributedStringView.swift in Sources */, 2963A9391EE258C20066509C /* GithubClient+Issues.swift in Sources */, 299F2A121EC3BCF0006CE9D7 /* GithubSessionManager.swift in Sources */, 29A195021EC66B8B00C3E289 /* UIColor+Hex.swift in Sources */, @@ -1272,7 +1271,6 @@ 2958407E1EEA00E1007723C6 /* IssueCommentModel.swift in Sources */, 295840D21EEA00E1007723C6 /* UIButton+Label.swift in Sources */, 2958409B1EEA00E1007723C6 /* IssueLabelDotCell.swift in Sources */, - 29C76D4D1EEB46B40048B23F /* UIView+NSAttributedStringSizing.swift in Sources */, 2958408F1EEA00E1007723C6 /* IssueCommentTextCell.swift in Sources */, 295840BC1EEA00E1007723C6 /* SettingsAddAccountSectionController.swift in Sources */, 2958407A1EEA00E1007723C6 /* IssueCommentImageCell.swift in Sources */,