Showing
3 changed files
with
119 additions
and
27 deletions
| ... | @@ -8,6 +8,31 @@ | ... | @@ -8,6 +8,31 @@ |
| 8 | import UIKit | 8 | import UIKit |
| 9 | 9 | ||
| 10 | extension UIViewController { | 10 | extension UIViewController { |
| 11 | + func addFloatingBackButton(icon: String = "ic_back_3") { | ||
| 12 | + let button = UIButton(type: .custom) | ||
| 13 | + button.translatesAutoresizingMaskIntoConstraints = false | ||
| 14 | + button.backgroundColor = .white | ||
| 15 | + button.layer.cornerRadius = 20 | ||
| 16 | + button.layer.shadowColor = UIColor.black.cgColor | ||
| 17 | + button.layer.shadowOpacity = 0.1 | ||
| 18 | + button.layer.shadowOffset = CGSize(width: 0, height: 2) | ||
| 19 | + button.layer.shadowRadius = 4 | ||
| 20 | + | ||
| 21 | + if let img = UIImage(named: icon, in: Bundle.frameworkResourceBundle, compatibleWith: nil) { | ||
| 22 | + button.setImage(img, for: .normal) | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + button.addTarget(self, action: #selector(moveToBack(_:)), for: .touchUpInside) | ||
| 26 | + | ||
| 27 | + self.view.addSubview(button) | ||
| 28 | + NSLayoutConstraint.activate([ | ||
| 29 | + button.widthAnchor.constraint(equalToConstant: 40), | ||
| 30 | + button.heightAnchor.constraint(equalToConstant: 40), | ||
| 31 | + button.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 16), | ||
| 32 | + button.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor, constant: 16) | ||
| 33 | + ]) | ||
| 34 | + } | ||
| 35 | + | ||
| 11 | func setBackButton(_ icon:String = "ic_back_3") { | 36 | func setBackButton(_ icon:String = "ic_back_3") { |
| 12 | // let uiscreen: CGRect = UIScreen.main.bounds | 37 | // let uiscreen: CGRect = UIScreen.main.bounds |
| 13 | 38 | ||
| ... | @@ -247,6 +272,20 @@ extension UIView { | ... | @@ -247,6 +272,20 @@ extension UIView { |
| 247 | lineLayer.path = path | 272 | lineLayer.path = path |
| 248 | self.layer.addSublayer(lineLayer) | 273 | self.layer.addSublayer(lineLayer) |
| 249 | } | 274 | } |
| 275 | + | ||
| 276 | + func addDashedBorder(color: UIColor, lineWidth: CGFloat = 1, dash: CGFloat = 3, gap: CGFloat = 3) { | ||
| 277 | + // Remove any existing dashed border layer to avoid duplicates on re-layout | ||
| 278 | + layer.sublayers?.removeAll(where: { $0.name == "dashedBorderLayer" }) | ||
| 279 | + | ||
| 280 | + let shapeLayer = CAShapeLayer() | ||
| 281 | + shapeLayer.name = "dashedBorderLayer" | ||
| 282 | + shapeLayer.strokeColor = color.cgColor | ||
| 283 | + shapeLayer.fillColor = UIColor.clear.cgColor | ||
| 284 | + shapeLayer.lineWidth = lineWidth | ||
| 285 | + shapeLayer.lineDashPattern = [dash as NSNumber, gap as NSNumber] | ||
| 286 | + shapeLayer.path = UIBezierPath(rect: bounds).cgPath | ||
| 287 | + layer.addSublayer(shapeLayer) | ||
| 288 | + } | ||
| 250 | } | 289 | } |
| 251 | 290 | ||
| 252 | extension UIImageView { | 291 | extension UIImageView { | ... | ... |
| ... | @@ -30,8 +30,10 @@ import UIKit | ... | @@ -30,8 +30,10 @@ import UIKit |
| 30 | @IBOutlet weak var favoriteImage: UIImageView! | 30 | @IBOutlet weak var favoriteImage: UIImageView! |
| 31 | @IBOutlet weak var shareImage: UIImageView! | 31 | @IBOutlet weak var shareImage: UIImageView! |
| 32 | 32 | ||
| 33 | + @IBOutlet weak var merchantNameLabel: UILabel! | ||
| 33 | @IBOutlet weak var titleLabel: UILabel! | 34 | @IBOutlet weak var titleLabel: UILabel! |
| 34 | @IBOutlet weak var subtitleLabel: UILabel! | 35 | @IBOutlet weak var subtitleLabel: UILabel! |
| 36 | + @IBOutlet weak var expirationView: UIView! | ||
| 35 | @IBOutlet weak var expirationLabel: UILabel! | 37 | @IBOutlet weak var expirationLabel: UILabel! |
| 36 | @IBOutlet weak var detailsLabel: UILabel! | 38 | @IBOutlet weak var detailsLabel: UILabel! |
| 37 | 39 | ||
| ... | @@ -75,9 +77,19 @@ import UIKit | ... | @@ -75,9 +77,19 @@ import UIKit |
| 75 | super.viewDidLoad() | 77 | super.viewDidLoad() |
| 76 | 78 | ||
| 77 | // Show navigation bar for this screen (with back button) | 79 | // Show navigation bar for this screen (with back button) |
| 78 | - self.navigationController?.setNavigationBarHidden(false, animated: false) | 80 | + // self.navigationController?.setNavigationBarHidden(false, animated: false) |
| 79 | - setBackButton() | 81 | + // setBackButton() |
| 80 | - setNavigationTitle("Προσφορά") | 82 | + // setNavigationTitle("Προσφορά") |
| 83 | + | ||
| 84 | + self.navigationController?.setNavigationBarHidden(true, animated: false) | ||
| 85 | + addFloatingBackButton() | ||
| 86 | + | ||
| 87 | + for label in [merchantNameLabel, titleLabel, subtitleLabel, expirationLabel, detailsLabel] { | ||
| 88 | + label?.setContentHuggingPriority(.defaultHigh, for: .vertical) | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + | ||
| 92 | + couponImage.backgroundColor = UIColor(rgb: 0x00A3E033) | ||
| 81 | 93 | ||
| 82 | infoView.backgroundColor = UIColor(rgb: 0xFFFFFF) | 94 | infoView.backgroundColor = UIColor(rgb: 0xFFFFFF) |
| 83 | infoView.layer.cornerRadius = 10.0 | 95 | infoView.layer.cornerRadius = 10.0 |
| ... | @@ -92,18 +104,26 @@ import UIKit | ... | @@ -92,18 +104,26 @@ import UIKit |
| 92 | infoLabel.textColor = UIColor(rgb: 0x020E1C) | 104 | infoLabel.textColor = UIColor(rgb: 0x020E1C) |
| 93 | infoLabel.text = "Περισσότερα" | 105 | infoLabel.text = "Περισσότερα" |
| 94 | 106 | ||
| 95 | - termsButtonTitleLabel.font = UIFont(name: "PingLCG-Bold", size: 16) | 107 | + expirationView.backgroundColor = UIColor(rgb: 0xDDEFFB) |
| 96 | - termsButtonTitleLabel.textColor = UIColor(rgb: 0x020E1C) | 108 | + expirationView.layer.cornerRadius = 6.0 |
| 97 | - termsButtonTitleLabel.text = "Όροι Χρήσης" | 109 | + expirationView.layer.borderWidth = 1.0 |
| 110 | + expirationView.layer.borderColor = UIColor(rgb: 0xCCE9FB).cgColor | ||
| 111 | + | ||
| 112 | + termsButtonTitleLabel.font = UIFont(name: "PingLCG-Bold", size: 15) | ||
| 113 | + termsButtonTitleLabel.textColor = UIColor(rgb: 0x5C6369) | ||
| 114 | + // termsButtonTitleLabel.text = "Όροι Χρήσης" | ||
| 115 | + termsButtonTitleLabel.text = "Offer terms of use" | ||
| 98 | termsButton.addTarget(self, action: #selector(toggleTerms), for: .touchUpInside) | 116 | termsButton.addTarget(self, action: #selector(toggleTerms), for: .touchUpInside) |
| 99 | termsLabelHeight.constant = 0 | 117 | termsLabelHeight.constant = 0 |
| 100 | 118 | ||
| 101 | - redeemButton.titleLabel?.font = UIFont(name: "PingLCG-Bold", size: 16) | 119 | + redeemButton.titleLabel?.font = UIFont(name: "PingLCG-Regular", size: 16) |
| 102 | - redeemButton.setTitle("Απόκτησε το κουπόνι", for: .normal) | 120 | + // redeemButton.setTitle("Απόκτησε το κουπόνι", for: .normal) |
| 121 | + redeemButton.setTitle("Get coupon", for: .normal) | ||
| 103 | redeemButton.setTitleColor(UIColor(rgb: 0xFFFFFF), for: .normal) | 122 | redeemButton.setTitleColor(UIColor(rgb: 0xFFFFFF), for: .normal) |
| 104 | redeemButton.setTitleColor(UIColor(rgb: 0xFFFFFF), for: .highlighted) | 123 | redeemButton.setTitleColor(UIColor(rgb: 0xFFFFFF), for: .highlighted) |
| 105 | - redeemButton.layer.cornerRadius = 4.0 | 124 | + redeemButton.layer.cornerRadius = redeemButton.bounds.height / 2 |
| 106 | - redeemButton.backgroundColor = UIColor(rgb: 0x000F1E) | 125 | + // redeemButton.backgroundColor = UIColor(rgb: 0x000F1E) |
| 126 | + redeemButton.backgroundColor = UIColor(rgb: 0x00A3E0) | ||
| 107 | redeemButton.addTarget(self, action: #selector(redeemButtonTapped), for: .touchUpInside) | 127 | redeemButton.addTarget(self, action: #selector(redeemButtonTapped), for: .touchUpInside) |
| 108 | 128 | ||
| 109 | // Configure the view with offer data | 129 | // Configure the view with offer data |
| ... | @@ -112,6 +132,28 @@ import UIKit | ... | @@ -112,6 +132,28 @@ import UIKit |
| 112 | } | 132 | } |
| 113 | } | 133 | } |
| 114 | 134 | ||
| 135 | + public override func viewDidLayoutSubviews() { | ||
| 136 | + super.viewDidLayoutSubviews() | ||
| 137 | + redeemButton.layer.cornerRadius = redeemButton.bounds.height / 2 | ||
| 138 | + | ||
| 139 | + couponImage.addDashedBorder( | ||
| 140 | + color: UIColor(rgb: 0x00A3E033), | ||
| 141 | + lineWidth: 1, | ||
| 142 | + dash: 3, | ||
| 143 | + gap: 3 | ||
| 144 | + ) | ||
| 145 | + } | ||
| 146 | + | ||
| 147 | + public override func viewWillAppear(_ animated: Bool) { | ||
| 148 | + super.viewWillAppear(animated) | ||
| 149 | + self.navigationController?.setNavigationBarHidden(true, animated: animated) | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + public override func viewWillDisappear(_ animated: Bool) { | ||
| 153 | + super.viewWillDisappear(animated) | ||
| 154 | + self.navigationController?.setNavigationBarHidden(false, animated: animated) | ||
| 155 | + } | ||
| 156 | + | ||
| 115 | @objc private func redeemButtonTapped() { | 157 | @objc private func redeemButtonTapped() { |
| 116 | guard let couponSetUuid = couponset?._uuid, !couponSetUuid.isEmpty else { | 158 | guard let couponSetUuid = couponset?._uuid, !couponSetUuid.isEmpty else { |
| 117 | showErrorAlert(message: "Δεν βρέθηκε το αναγνωριστικό της προσφοράς.") | 159 | showErrorAlert(message: "Δεν βρέθηκε το αναγνωριστικό της προσφοράς.") |
| ... | @@ -216,23 +258,28 @@ import UIKit | ... | @@ -216,23 +258,28 @@ import UIKit |
| 216 | // Default to not favorite for coupon sets | 258 | // Default to not favorite for coupon sets |
| 217 | favoriteImage.image = UIImage(named: "favorite2_empty", in: Bundle.frameworkResourceBundle, compatibleWith: nil) | 259 | favoriteImage.image = UIImage(named: "favorite2_empty", in: Bundle.frameworkResourceBundle, compatibleWith: nil) |
| 218 | 260 | ||
| 261 | + merchantNameLabel.font = UIFont(name: "PingLCG-Bold", size: 15) | ||
| 262 | + merchantNameLabel.textColor = UIColor(rgb: 0x9BA1A6) | ||
| 263 | + merchantNameLabel.text = couponset._merchant?._name | ||
| 264 | + | ||
| 219 | titleLabel.font = UIFont(name: "PingLCG-Bold", size: 24) | 265 | titleLabel.font = UIFont(name: "PingLCG-Bold", size: 24) |
| 220 | - titleLabel.textColor = UIColor(rgb: 0xF2709D) | 266 | + titleLabel.textColor = UIColor(rgb: 0x000F1E) |
| 221 | titleLabel.text = couponset._name | 267 | titleLabel.text = couponset._name |
| 222 | 268 | ||
| 223 | subtitleLabel.font = UIFont(name: "PingLCG-Regular", size: 18) | 269 | subtitleLabel.font = UIFont(name: "PingLCG-Regular", size: 18) |
| 224 | - subtitleLabel.textColor = UIColor(rgb: 0x020E1C) | 270 | + subtitleLabel.textColor = UIColor(rgb: 0x000F1E) |
| 225 | subtitleLabel.text = couponset._short_description | 271 | subtitleLabel.text = couponset._short_description |
| 226 | 272 | ||
| 227 | - expirationLabel.font = UIFont(name: "PingLCG-Regular", size: 14) | 273 | + expirationLabel.font = UIFont(name: "PingLCG-Bold", size: 13) |
| 228 | - expirationLabel.textColor = UIColor(rgb: 0x020E1C) | 274 | + expirationLabel.textColor = UIColor(rgb: 0x002430) |
| 229 | - expirationLabel.text = ("Η προσφορά ισχύει έως " + couponset.formattedEndDate(format: "dd-MM-yyyy")) | 275 | + expirationLabel.text = ("Valid until " + couponset.formattedEndDate(format: "MMMM d, yyyy")) |
| 276 | +// expirationLabel.text = ("Η προσφορά ισχύει έως " + couponset.formattedEndDate(format: "dd-MM-yyyy")) | ||
| 230 | // expirationLabel.text = "Η προσφορά ισχύει έως 30-09-2025" | 277 | // expirationLabel.text = "Η προσφορά ισχύει έως 30-09-2025" |
| 231 | 278 | ||
| 232 | setupExpandableDetails() | 279 | setupExpandableDetails() |
| 233 | 280 | ||
| 234 | - termsLabel.font = UIFont(name: "PingLCG-Regular", size: 16) | 281 | + termsLabel.font = UIFont(name: "PingLCG-Regular", size: 15) |
| 235 | - termsLabel.textColor = UIColor(rgb: 0x020E1C) | 282 | + termsLabel.textColor = UIColor(rgb: 0x5C6369) |
| 236 | // termsLabel.text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sed ex euismod, feugiat justo eu, faucibus urna. Nulla sodales euismod arcu volutpat finibus. Etiam id urna at justo facilisis tempor. Morbi dignissim erat vitae magna sodales dignissim ac in mauris. Mauris tempor convallis tortor, interdum hendrerit turpis eleifend at. Praesent." | 283 | // termsLabel.text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sed ex euismod, feugiat justo eu, faucibus urna. Nulla sodales euismod arcu volutpat finibus. Etiam id urna at justo facilisis tempor. Morbi dignissim erat vitae magna sodales dignissim ac in mauris. Mauris tempor convallis tortor, interdum hendrerit turpis eleifend at. Praesent." |
| 237 | termsLabel.text = couponset._terms | 284 | termsLabel.text = couponset._terms |
| 238 | } | 285 | } |
| ... | @@ -244,8 +291,8 @@ import UIKit | ... | @@ -244,8 +291,8 @@ import UIKit |
| 244 | // fullDetailsText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sed ex euismod, feugiat justo eu, faucibus urna. Nulla sodales euismod arcu volutpat finibus. Etiam id urna at justo facilisis tempor. Morbi dignissim erat vitae magna sodales dignissim ac in mauris. Mauris tempor convallis tortor, interdum hendrerit turpis eleifend at. Praesent." | 291 | // fullDetailsText = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sed ex euismod, feugiat justo eu, faucibus urna. Nulla sodales euismod arcu volutpat finibus. Etiam id urna at justo facilisis tempor. Morbi dignissim erat vitae magna sodales dignissim ac in mauris. Mauris tempor convallis tortor, interdum hendrerit turpis eleifend at. Praesent." |
| 245 | fullDetailsText = couponset?._description ?? "" | 292 | fullDetailsText = couponset?._description ?? "" |
| 246 | 293 | ||
| 247 | - detailsLabel.font = UIFont(name: "PingLCG-Regular", size: 18) | 294 | + detailsLabel.font = UIFont(name: "PingLCG-Regular", size: 16) |
| 248 | - detailsLabel.textColor = UIColor(rgb: 0x020E1C) | 295 | + detailsLabel.textColor = UIColor(rgb: 0x5C6369) |
| 249 | 296 | ||
| 250 | updateDetailsText() | 297 | updateDetailsText() |
| 251 | 298 | ||
| ... | @@ -258,8 +305,11 @@ import UIKit | ... | @@ -258,8 +305,11 @@ import UIKit |
| 258 | if isDetailsExpanded { | 305 | if isDetailsExpanded { |
| 259 | // Show full text with "Λιγότερα" | 306 | // Show full text with "Λιγότερα" |
| 260 | if (shouldTruncaitDetails) { | 307 | if (shouldTruncaitDetails) { |
| 261 | - let fullTextWithLess = fullDetailsText + " Λιγότερα" | 308 | +// let fullTextWithLess = fullDetailsText + " Λιγότερα" |
| 262 | - let attributedString = createAttributedString(text: fullTextWithLess, linkText: "Λιγότερα") | 309 | +// let attributedString = createAttributedString(text: fullTextWithLess, linkText: "Λιγότερα") |
| 310 | + | ||
| 311 | + let fullTextWithLess = fullDetailsText + " View less" | ||
| 312 | + let attributedString = createAttributedString(text: fullTextWithLess, linkText: "View less") | ||
| 263 | detailsLabel.attributedText = attributedString | 313 | detailsLabel.attributedText = attributedString |
| 264 | } else { | 314 | } else { |
| 265 | detailsLabel.text = fullDetailsText | 315 | detailsLabel.text = fullDetailsText |
| ... | @@ -267,8 +317,10 @@ import UIKit | ... | @@ -267,8 +317,10 @@ import UIKit |
| 267 | detailsLabel.numberOfLines = 0 | 317 | detailsLabel.numberOfLines = 0 |
| 268 | } else { | 318 | } else { |
| 269 | // Calculate approximate characters for 4 lines and truncate if needed | 319 | // Calculate approximate characters for 4 lines and truncate if needed |
| 320 | +// let truncatedText = getTruncatedTextForFourLines() | ||
| 321 | +// let attributedString = createAttributedString(text: truncatedText, linkText: "Περισσότερα") | ||
| 270 | let truncatedText = getTruncatedTextForFourLines() | 322 | let truncatedText = getTruncatedTextForFourLines() |
| 271 | - let attributedString = createAttributedString(text: truncatedText, linkText: "Περισσότερα") | 323 | + let attributedString = createAttributedString(text: truncatedText, linkText: "View more") |
| 272 | detailsLabel.attributedText = attributedString | 324 | detailsLabel.attributedText = attributedString |
| 273 | detailsLabel.numberOfLines = 4 | 325 | detailsLabel.numberOfLines = 4 |
| 274 | } | 326 | } |
| ... | @@ -282,7 +334,8 @@ import UIKit | ... | @@ -282,7 +334,8 @@ import UIKit |
| 282 | let charactersPerLine = Int(labelWidth / averageCharWidth) | 334 | let charactersPerLine = Int(labelWidth / averageCharWidth) |
| 283 | let maxCharactersFor4Lines = charactersPerLine * 4 | 335 | let maxCharactersFor4Lines = charactersPerLine * 4 |
| 284 | 336 | ||
| 285 | - let moreText = " Περισσότερα" | 337 | +// let moreText = " Περισσότερα" |
| 338 | + let moreText = " View more" | ||
| 286 | let ellipsis = "..." | 339 | let ellipsis = "..." |
| 287 | let reservedCharacters = ellipsis.count + moreText.count + 15 | 340 | let reservedCharacters = ellipsis.count + moreText.count + 15 |
| 288 | 341 | ||
| ... | @@ -307,14 +360,14 @@ import UIKit | ... | @@ -307,14 +360,14 @@ import UIKit |
| 307 | 360 | ||
| 308 | // Regular text attributes | 361 | // Regular text attributes |
| 309 | let regularAttributes: [NSAttributedString.Key: Any] = [ | 362 | let regularAttributes: [NSAttributedString.Key: Any] = [ |
| 310 | - .font: UIFont(name: "PingLCG-Regular", size: 18) ?? UIFont.systemFont(ofSize: 18), | 363 | + .font: UIFont(name: "PingLCG-Regular", size: 16) ?? UIFont.systemFont(ofSize: 16), |
| 311 | - .foregroundColor: UIColor(rgb: 0x020E1C) | 364 | + .foregroundColor: UIColor(rgb: 0x5C6369) |
| 312 | ] | 365 | ] |
| 313 | 366 | ||
| 314 | // Link text attributes (blue color) | 367 | // Link text attributes (blue color) |
| 315 | let linkAttributes: [NSAttributedString.Key: Any] = [ | 368 | let linkAttributes: [NSAttributedString.Key: Any] = [ |
| 316 | - .font: UIFont(name: "PingLCG-Regular", size: 18) ?? UIFont.systemFont(ofSize: 18), | 369 | + .font: UIFont(name: "PingLCG-Bold", size: 16) ?? UIFont.systemFont(ofSize: 16), |
| 317 | - .foregroundColor: UIColor(rgb: 0x00A8E8) // Blue color | 370 | + .foregroundColor: UIColor(rgb: 0x1D2023) // Blue color |
| 318 | ] | 371 | ] |
| 319 | 372 | ||
| 320 | // Apply regular attributes to entire text | 373 | // Apply regular attributes to entire text | ... | ... |
This diff is collapsed. Click to expand it.
-
Please register or login to post a comment