Showing
4 changed files
with
84 additions
and
2 deletions
No preview for this file type
| ... | @@ -10,7 +10,7 @@ import UIKit | ... | @@ -10,7 +10,7 @@ import UIKit |
| 10 | import AVFoundation | 10 | import AVFoundation |
| 11 | // import SwiftEventBus | 11 | // import SwiftEventBus |
| 12 | 12 | ||
| 13 | -@objc public class CouponBarcodeViewController: UIViewController { | 13 | +@objc public class CouponBarcodeViewController: UIViewController, UITextViewDelegate { |
| 14 | @IBOutlet weak var mainView: UIView! | 14 | @IBOutlet weak var mainView: UIView! |
| 15 | @IBOutlet weak var backgroundImage: UIImageView! | 15 | @IBOutlet weak var backgroundImage: UIImageView! |
| 16 | @IBOutlet weak var scrollView: UIScrollView! | 16 | @IBOutlet weak var scrollView: UIScrollView! |
| ... | @@ -19,6 +19,9 @@ import AVFoundation | ... | @@ -19,6 +19,9 @@ import AVFoundation |
| 19 | @IBOutlet weak var couponImageHeight: NSLayoutConstraint! | 19 | @IBOutlet weak var couponImageHeight: NSLayoutConstraint! |
| 20 | @IBOutlet weak var nameLabel: UILabel! | 20 | @IBOutlet weak var nameLabel: UILabel! |
| 21 | @IBOutlet weak var discriptionLabel: UILabel! | 21 | @IBOutlet weak var discriptionLabel: UILabel! |
| 22 | + @IBOutlet weak var merchantDescrTextView: UnselectableTappableTextView! | ||
| 23 | + @IBOutlet weak var merchantDescrTextViewHeight: NSLayoutConstraint! | ||
| 24 | + @IBOutlet weak var merchantDescrTextViewTopSpace: NSLayoutConstraint! | ||
| 22 | @IBOutlet weak var couponView: UIView! | 25 | @IBOutlet weak var couponView: UIView! |
| 23 | @IBOutlet weak var couponNumberLabel: CopyableLabel! | 26 | @IBOutlet weak var couponNumberLabel: CopyableLabel! |
| 24 | @IBOutlet weak var barcodeImage: UIImageView! | 27 | @IBOutlet weak var barcodeImage: UIImageView! |
| ... | @@ -29,7 +32,7 @@ import AVFoundation | ... | @@ -29,7 +32,7 @@ import AVFoundation |
| 29 | @IBOutlet weak var expirationLabel: UILabel! | 32 | @IBOutlet weak var expirationLabel: UILabel! |
| 30 | @IBOutlet weak var redeemButton: UIButton! | 33 | @IBOutlet weak var redeemButton: UIButton! |
| 31 | @IBOutlet weak var termsButton: UIButton! | 34 | @IBOutlet weak var termsButton: UIButton! |
| 32 | - @IBOutlet weak var termsTextView: UITextView! | 35 | + @IBOutlet weak var termsTextView: UnselectableTappableTextView! |
| 33 | @IBOutlet weak var termsTextViewHeight: NSLayoutConstraint! | 36 | @IBOutlet weak var termsTextViewHeight: NSLayoutConstraint! |
| 34 | @IBOutlet weak var borderViewHeight: NSLayoutConstraint! | 37 | @IBOutlet weak var borderViewHeight: NSLayoutConstraint! |
| 35 | @IBOutlet weak var borderView2Height: NSLayoutConstraint! | 38 | @IBOutlet weak var borderView2Height: NSLayoutConstraint! |
| ... | @@ -60,6 +63,8 @@ import AVFoundation | ... | @@ -60,6 +63,8 @@ import AVFoundation |
| 60 | super.viewDidLoad() | 63 | super.viewDidLoad() |
| 61 | 64 | ||
| 62 | self.hidesBottomBarWhenPushed = true | 65 | self.hidesBottomBarWhenPushed = true |
| 66 | + merchantDescrTextView.delegate = self | ||
| 67 | + termsTextView.delegate = self | ||
| 63 | 68 | ||
| 64 | // Do any additional setup after loading the view. | 69 | // Do any additional setup after loading the view. |
| 65 | setBackButton() | 70 | setBackButton() |
| ... | @@ -101,6 +106,38 @@ import AVFoundation | ... | @@ -101,6 +106,38 @@ import AVFoundation |
| 101 | nameLabel.text = couponSetData?.name ?? "" | 106 | nameLabel.text = couponSetData?.name ?? "" |
| 102 | discriptionLabel.text = couponSetData?.short_description ?? "" | 107 | discriptionLabel.text = couponSetData?.short_description ?? "" |
| 103 | 108 | ||
| 109 | + merchantDescrTextView.text = "" | ||
| 110 | + merchantDescrTextViewTopSpace.constant = CGFloat(0) | ||
| 111 | + merchantDescrTextViewHeight.constant = CGFloat(0) | ||
| 112 | + merchantDescrTextView.isHidden = true | ||
| 113 | + | ||
| 114 | + let merchantList:Array<swiftApi.MerchantModel> = swiftApi().getMerchantList() | ||
| 115 | + | ||
| 116 | + for merchant in merchantList { | ||
| 117 | + if (merchant._uuid == couponSetData?.merchant_uuid) { | ||
| 118 | + let htmlMerchDescrText = merchant._body | ||
| 119 | + | ||
| 120 | + if (htmlMerchDescrText != "") { | ||
| 121 | + merchantDescrTextView.attributedText = htmlMerchDescrText.htmlToAttributedString | ||
| 122 | + merchantDescrTextView.font = UIFont(name: "PFSquareSansPro-Regular", size: 17) | ||
| 123 | + merchantDescrTextView.textColor = UIColor(red: 0.25, green: 0.33, blue: 0.39, alpha: 1.00) | ||
| 124 | + merchantDescrTextView.textAlignment = .center | ||
| 125 | + merchantDescrTextView.isScrollEnabled = false | ||
| 126 | + merchantDescrTextView.isUserInteractionEnabled = true | ||
| 127 | + merchantDescrTextView.isEditable = false | ||
| 128 | + merchantDescrTextView.isSelectable = true | ||
| 129 | + merchantDescrTextView.dataDetectorTypes = [.link] | ||
| 130 | + | ||
| 131 | + merchantDescrTextView.isHidden = false | ||
| 132 | + merchantDescrTextViewTopSpace.constant = CGFloat(15) | ||
| 133 | + let targetSize = CGSize(width: merchantDescrTextView.frame.width, height: CGFloat(MAXFLOAT)) | ||
| 134 | + merchantDescrTextViewHeight.constant = merchantDescrTextView.sizeThatFits(targetSize).height | ||
| 135 | + } | ||
| 136 | + | ||
| 137 | + break; | ||
| 138 | + } | ||
| 139 | + } | ||
| 140 | + | ||
| 104 | couponView.layer.cornerRadius = 8 | 141 | couponView.layer.cornerRadius = 8 |
| 105 | couponNumberLabel.text = coupon?.coupon ?? "" | 142 | couponNumberLabel.text = coupon?.coupon ?? "" |
| 106 | couponView.frame = CGRect(x: 0.0, y: 0.0, width: couponView.intrinsicContentSize.width, height: 55) | 143 | couponView.frame = CGRect(x: 0.0, y: 0.0, width: couponView.intrinsicContentSize.width, height: 55) |
| ... | @@ -246,6 +283,11 @@ import AVFoundation | ... | @@ -246,6 +283,11 @@ import AVFoundation |
| 246 | termsTextView.textAlignment = .center | 283 | termsTextView.textAlignment = .center |
| 247 | termsTextView.isScrollEnabled = false | 284 | termsTextView.isScrollEnabled = false |
| 248 | 285 | ||
| 286 | + termsTextView.isUserInteractionEnabled = true | ||
| 287 | + termsTextView.isEditable = false | ||
| 288 | + termsTextView.isSelectable = true | ||
| 289 | + termsTextView.dataDetectorTypes = [.link] | ||
| 290 | + | ||
| 249 | // Uncomment if Barcode Section is active again | 291 | // Uncomment if Barcode Section is active again |
| 250 | // toggleTerms() | 292 | // toggleTerms() |
| 251 | toggleBarcode() | 293 | toggleBarcode() |
| ... | @@ -265,6 +307,14 @@ import AVFoundation | ... | @@ -265,6 +307,14 @@ import AVFoundation |
| 265 | 307 | ||
| 266 | } | 308 | } |
| 267 | 309 | ||
| 310 | + public func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool { | ||
| 311 | + UIApplication.shared.open(URL) | ||
| 312 | + | ||
| 313 | + // Disable `.preview` by 3D Touch and other interactions | ||
| 314 | + return false | ||
| 315 | + } | ||
| 316 | + | ||
| 317 | + | ||
| 268 | // MARK: - Functions | 318 | // MARK: - Functions |
| 269 | func toggleTerms() { | 319 | func toggleTerms() { |
| 270 | if (termsVisible) { | 320 | if (termsVisible) { | ... | ... |
This diff is collapsed. Click to expand it.
| ... | @@ -490,3 +490,35 @@ extension UINavigationController { | ... | @@ -490,3 +490,35 @@ extension UINavigationController { |
| 490 | return nil | 490 | return nil |
| 491 | } | 491 | } |
| 492 | } | 492 | } |
| 493 | + | ||
| 494 | +/// Class to allow links but no selection. | ||
| 495 | +/// Basically, it disables unwanted UIGestureRecognizer from UITextView. | ||
| 496 | +class UnselectableTappableTextView: UITextView { | ||
| 497 | + | ||
| 498 | + // required to prevent blue background selection from any situation | ||
| 499 | + override var selectedTextRange: UITextRange? { | ||
| 500 | + get { return nil } | ||
| 501 | + set {} | ||
| 502 | + } | ||
| 503 | + | ||
| 504 | + override func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { | ||
| 505 | + if gestureRecognizer is UIPanGestureRecognizer { | ||
| 506 | + // required for compatibility with isScrollEnabled | ||
| 507 | + return super.gestureRecognizerShouldBegin(gestureRecognizer) | ||
| 508 | + } | ||
| 509 | + if let tapGestureRecognizer = gestureRecognizer as? UITapGestureRecognizer, | ||
| 510 | + tapGestureRecognizer.numberOfTapsRequired == 1 { | ||
| 511 | + // required for compatibility with links | ||
| 512 | + return super.gestureRecognizerShouldBegin(gestureRecognizer) | ||
| 513 | + } | ||
| 514 | + // allowing smallDelayRecognizer for links | ||
| 515 | + if let longPressGestureRecognizer = gestureRecognizer as? UILongPressGestureRecognizer, | ||
| 516 | + // comparison value is used to distinguish between 0.12 (smallDelayRecognizer) and 0.5 (textSelectionForce and textLoupe) | ||
| 517 | + longPressGestureRecognizer.minimumPressDuration < 0.325 { | ||
| 518 | + return super.gestureRecognizerShouldBegin(gestureRecognizer) | ||
| 519 | + } | ||
| 520 | + // preventing selection from loupe/magnifier (_UITextSelectionForceGesture), multi tap, tap and a half, etc. | ||
| 521 | + gestureRecognizer.isEnabled = false | ||
| 522 | + return false | ||
| 523 | + } | ||
| 524 | +} | ... | ... |
-
Please register or login to post a comment