Commit 6a81dbf7 by Demid Merzlyakov

IOS-155: sub description view layout.

parent 08a4f9e1
{
"images" : [
{
"filename" : "group.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}
{
"images" : [
{
"filename" : "Group 2.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}
{
"images" : [
{
"filename" : "Star.pdf",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"preserves-vector-representation" : true
}
}
{
"colors" : [
{
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.780",
"green" : "0.940",
"red" : "0.991"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.780",
"green" : "0.940",
"red" : "0.991"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
{
"colors" : [
{
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.329",
"green" : "0.795",
"red" : "0.966"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.329",
"green" : "0.795",
"red" : "0.966"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
......@@ -215,6 +215,20 @@
//Subscriptions
"subscription.header.oneWeather" = "1Weather";
"subscription.header.premium" = "PREMIUM";
"subscription.description.header" = "Get the best of 1 Weather";
"subscription.description.header.purchased" = "Thank you for subscribing to 1Weather Premium";
"subscription.description.items.youGet" = "You get:";
"subscription.description.items.adFree" = "Ad free experience";
"subscription.description.items.adFree.forever" = "Forever";
"subscription.description.items.hourly" = " 48 hours of Hourly forecasts";
"subscription.description.items.hourly.crossed" = "24 hours";
"subscription.description.items.daily" = " 10 Days of Daily forecasts";
"subscription.description.items.daily.crossed" = "7 days";
"subscription.description.items.aqi" = "AQI card";
"subscription.description.items.comingSoon" = "Coming Soon";
"subscription.description.items.minutely" = "Minutely Forecast";
"subscription.button.buy.yearly" = "Subscribe yearly for #PRICE#";
"subscription.button.buy.monthly" = "Subscribe monthly for #PRICE#";
"subscription.button.upgrade.yearly" = "Upgrade for #PRICE# #DISCOUNT_PRICE# / year";
......
......@@ -87,7 +87,7 @@ extension SubscriptionStoreViewController {
}
else {
descriptionView = SubscriptionDescriptionView()
descriptionView = SubscriptionDescriptionView(alreadyPurchased: false)
}
dynamicContentView.addSubview(descriptionView)
descriptionView.snp.makeConstraints { make in
......@@ -120,7 +120,7 @@ extension SubscriptionStoreViewController {
}
lastView.snp.makeConstraints { make in
make.bottom.equalToSuperview()
make.bottom.equalToSuperview().inset(32)
}
}
}
......
......@@ -6,16 +6,211 @@
//
import UIKit
import SnapKit
/// A view containing decription of features of premium subscription for users who HAVE NOT previously purchased an in-app to remove ads.
class SubscriptionDescriptionView: UIView {
public init() {
private let header = UILabel()
private let stackView = UIStackView()
private let alreadyPurchased: Bool
public init(alreadyPurchased: Bool) {
self.alreadyPurchased = alreadyPurchased
super.init(frame: .zero)
self.translatesAutoresizingMaskIntoConstraints = false
prepareHeader()
prepareStackView()
prepareItems()
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func prepareHeader() {
header.font = AppFont.SFPro.semibold(size: 24)
header.textColor = ThemeManager.currentTheme.primaryTextColor
header.numberOfLines = 0
header.textAlignment = .center
if alreadyPurchased {
header.text = "subscription.description.header.purchased".localized()
}
else {
header.text = "subscription.description.header".localized()
}
addSubview(header)
header.snp.makeConstraints { make in
make.top.equalToSuperview().inset(32)
make.centerX.equalToSuperview()
make.left.greaterThanOrEqualToSuperview()
make.right.lessThanOrEqualToSuperview()
}
}
private func prepareStackView() {
addSubview(stackView)
stackView.axis = .vertical
stackView.spacing = 24
stackView.alignment = .leading
stackView.snp.makeConstraints { make in
make.top.equalTo(header.snp.bottom).offset(28)
make.left.right.bottom.equalToSuperview()
}
}
private func prepareItems() {
let checkmarkImage = UIImage(named: "subscription_checkmark") ?? UIImage()
let starImage = UIImage(named: "subscription_star") ?? UIImage()
if alreadyPurchased {
let youGetLabel = UILabel()
youGetLabel.font = AppFont.SFPro.bold(size: 16)
youGetLabel.textColor = ThemeManager.currentTheme.primaryTextColor
youGetLabel.text = "subscription.description.items.youGet".localized()
stackView.addArrangedSubview(youGetLabel)
}
let adFreeItem = DescriptionItemView(image: checkmarkImage, textShortLocalizedKey: "items.adFree")
stackView.addArrangedSubview(adFreeItem)
let forever = prepareForeverMarker()
addSubview(forever)
forever.snp.makeConstraints { make in
make.leading.equalTo(adFreeItem.snp.trailing).offset(8)
make.centerY.equalTo(adFreeItem.snp.centerY)
}
let hourlyItem = DescriptionItemView(image: checkmarkImage, textShortLocalizedKey: "items.hourly", crossedOutTextShortLocalizedKey: "items.hourly.crossed")
stackView.addArrangedSubview(hourlyItem)
let dailyItem = DescriptionItemView(image: checkmarkImage, textShortLocalizedKey: "items.daily", crossedOutTextShortLocalizedKey: "items.daily.crossed")
stackView.addArrangedSubview(dailyItem)
let aqiItem = DescriptionItemView(image: checkmarkImage, textShortLocalizedKey: "items.aqi")
stackView.addArrangedSubview(aqiItem)
let comingSoonSpacerView = UIView()
comingSoonSpacerView.backgroundColor = .clear
comingSoonSpacerView.snp.makeConstraints { make in
make.height.equalTo(8)
}
stackView.addArrangedSubview(comingSoonSpacerView)
let comingSoonView = prepareComingSoon()
addSubview(comingSoonView)
comingSoonView.snp.makeConstraints { make in
make.leading.equalTo(self.snp.leading).inset(-24) // a hack)
make.centerY.equalTo(comingSoonSpacerView.snp.centerY)
}
let minutelyItem = DescriptionItemView(image: starImage, textShortLocalizedKey: "items.minutely")
stackView.addArrangedSubview(minutelyItem)
}
private func prepareForeverMarker() -> UIView {
let nonClippingView = UIView()
nonClippingView.clipsToBounds = false
let view = UIView()
view.backgroundColor = UIColor(named: "subscription_no_ads_forever_background")
view.layer.cornerRadius = 4
view.clipsToBounds = true
let label = UILabel()
view.addSubview(label)
label.font = AppFont.SFPro.semibold(size: 10)
label.text = "subscription.description.items.adFree.forever".localized()
label.snp.makeConstraints { make in
make.top.equalToSuperview().inset(2)
make.bottom.equalToSuperview().inset(3)
make.left.right.equalToSuperview().inset(6)
}
nonClippingView.addSubview(view)
view.snp.makeConstraints { make in
make.top.left.right.bottom.equalToSuperview()
}
let raysIcon = UIImageView()
raysIcon.image = UIImage(named: "subscription_no_ads_forever_rays")
nonClippingView.addSubview(raysIcon)
raysIcon.snp.makeConstraints { make in
make.width.height.equalTo(16)
make.bottom.equalTo(view.snp.top).offset(4)
make.leading.equalTo(view.snp.trailing).offset(-4)
}
return nonClippingView
}
private func prepareComingSoon() -> UIView {
let view = UIView()
view.backgroundColor = UIColor(named: "subscription_coming_soon_background")
view.layer.cornerRadius = 12
view.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMaxXMaxYCorner]
view.clipsToBounds = true
let label = UILabel()
view.addSubview(label)
label.font = AppFont.SFPro.semibold(size: 10)
label.text = "subscription.description.items.comingSoon".localized()
label.snp.makeConstraints { make in
make.top.bottom.equalToSuperview().inset(6)
make.left.right.equalToSuperview().inset(12)
}
return view
}
}
extension SubscriptionDescriptionView {
private class DescriptionItemView: UIView {
private let iconView = UIImageView()
private let textView = UILabel()
public init(image: UIImage, textShortLocalizedKey: String, crossedOutTextShortLocalizedKey: String? = nil) {
textView.textColor = ThemeManager.currentTheme.primaryTextColor
let text = ("subscription.description." + textShortLocalizedKey).localized()
super.init(frame: .zero)
self.translatesAutoresizingMaskIntoConstraints = false
let defaultAttributes: [NSAttributedString.Key: Any] = [
NSAttributedString.Key.font: AppFont.SFPro.regular(size: 16)
]
let attributedText = NSMutableAttributedString(string: text, attributes: defaultAttributes)
if let crossedOutTextShortLocalizedKey = crossedOutTextShortLocalizedKey {
let crossedOutText = ("subscription.description." + crossedOutTextShortLocalizedKey).localized()
let crossedOutAttributes: [NSAttributedString.Key: Any] = [
NSAttributedString.Key.font: AppFont.SFPro.light(size: 16),
NSAttributedString.Key.strikethroughStyle: NSUnderlineStyle.single.rawValue
]
attributedText.insert(NSAttributedString(string: crossedOutText, attributes: crossedOutAttributes), at: 0)
}
textView.attributedText = attributedText
iconView.image = image
addSubview(iconView)
addSubview(textView)
iconView.snp.makeConstraints { make in
make.height.width.equalTo(20)
make.leading.top.bottom.equalToSuperview()
}
textView.snp.makeConstraints { make in
make.top.bottom.equalToSuperview()
make.leading.equalTo(iconView.snp.trailing).offset(10)
make.trailing.equalToSuperview()
}
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment