From 339105847543e6bcd8b1d93dce57398a1c63211a Mon Sep 17 00:00:00 2001 From: Riley Testut Date: Fri, 8 Dec 2023 18:30:30 -0600 Subject: [PATCH] Fixes button titles flashing when scrolling into view --- AltStore/Browse/FeaturedViewController.swift | 5 +- AltStore/Components/AppBannerView.swift | 126 ++++++++++--------- AltStore/Sources/SourcesViewController.swift | 48 +++---- 3 files changed, 93 insertions(+), 86 deletions(-) diff --git a/AltStore/Browse/FeaturedViewController.swift b/AltStore/Browse/FeaturedViewController.swift index ef463802..67555d0e 100644 --- a/AltStore/Browse/FeaturedViewController.swift +++ b/AltStore/Browse/FeaturedViewController.swift @@ -566,7 +566,10 @@ extension FeaturedViewController content.imageProperties.maximumSize = CGSize(width: 26, height: 26) content.imageProperties.cornerRadius = 13 - headerView.titleButton.setTitle(content.text, for: .normal) + UIView.performWithoutAnimation { + headerView.titleButton.setTitle(content.text, for: .normal) + headerView.titleButton.layoutIfNeeded() + } headerView.iconButton.backgroundColor = storeApp.source?.effectiveTintColor?.adjustedForDisplay headerView.iconButton.setImage(nil, for: .normal) diff --git a/AltStore/Components/AppBannerView.swift b/AltStore/Components/AppBannerView.swift index f4d9b3d1..9291996f 100644 --- a/AltStore/Components/AppBannerView.swift +++ b/AltStore/Components/AppBannerView.swift @@ -254,83 +254,85 @@ extension AppBannerView buttonAction = .open } - switch buttonAction - { - case .open: - let buttonTitle = NSLocalizedString("Open", comment: "") - self.button.setTitle(buttonTitle.uppercased(), for: .normal) - self.button.accessibilityLabel = String(format: NSLocalizedString("Open %@", comment: ""), values.name) - self.button.accessibilityValue = buttonTitle - - self.button.countdownDate = nil - - case .update: - let buttonTitle = NSLocalizedString("Update", comment: "") - self.button.setTitle(buttonTitle.uppercased(), for: .normal) - self.button.accessibilityLabel = String(format: NSLocalizedString("Update %@", comment: ""), values.name) - self.button.accessibilityValue = buttonTitle - - self.button.countdownDate = nil - - case .custom(let buttonTitle): - self.button.setTitle(buttonTitle, for: .normal) - self.button.accessibilityLabel = buttonTitle - self.button.accessibilityValue = buttonTitle - - self.button.countdownDate = nil - - case .install: - if let storeApp = app.storeApp, storeApp.isPledgeRequired + UIView.performWithoutAnimation { + switch buttonAction { - // Pledge required + case .open: + let buttonTitle = NSLocalizedString("Open", comment: "") + self.button.setTitle(buttonTitle.uppercased(), for: .normal) + self.button.accessibilityLabel = String(format: NSLocalizedString("Open %@", comment: ""), values.name) + self.button.accessibilityValue = buttonTitle - if storeApp.isPledged + self.button.countdownDate = nil + + case .update: + let buttonTitle = NSLocalizedString("Update", comment: "") + self.button.setTitle(buttonTitle.uppercased(), for: .normal) + self.button.accessibilityLabel = String(format: NSLocalizedString("Update %@", comment: ""), values.name) + self.button.accessibilityValue = buttonTitle + + self.button.countdownDate = nil + + case .custom(let buttonTitle): + self.button.setTitle(buttonTitle, for: .normal) + self.button.accessibilityLabel = buttonTitle + self.button.accessibilityValue = buttonTitle + + self.button.countdownDate = nil + + case .install: + if let storeApp = app.storeApp, storeApp.isPledgeRequired { - let buttonTitle = NSLocalizedString("Install", comment: "") - self.button.setTitle(buttonTitle.uppercased(), for: .normal) - self.button.accessibilityLabel = String(format: NSLocalizedString("Install %@", comment: ""), app.name) - self.button.accessibilityValue = buttonTitle - } - else if let amount = storeApp.pledgeAmount, let currencyCode = storeApp.pledgeCurrency, #available(iOS 15, *) - { - let price = amount.formatted(.currency(code: currencyCode).presentation(.narrow).precision(.fractionLength(0...2))) + // Pledge required - let buttonTitle = String(format: NSLocalizedString("%@/mo", comment: ""), price) - self.button.setTitle(buttonTitle, for: .normal) - self.button.accessibilityLabel = String(format: NSLocalizedString("Pledge %@ a month", comment: ""), price) - self.button.accessibilityValue = String(format: NSLocalizedString("%@ a month", comment: ""), price) + if storeApp.isPledged + { + let buttonTitle = NSLocalizedString("Install", comment: "") + self.button.setTitle(buttonTitle.uppercased(), for: .normal) + self.button.accessibilityLabel = String(format: NSLocalizedString("Install %@", comment: ""), app.name) + self.button.accessibilityValue = buttonTitle + } + else if let amount = storeApp.pledgeAmount, let currencyCode = storeApp.pledgeCurrency, #available(iOS 15, *) + { + let price = amount.formatted(.currency(code: currencyCode).presentation(.narrow).precision(.fractionLength(0...2))) + + let buttonTitle = String(format: NSLocalizedString("%@/mo", comment: ""), price) + self.button.setTitle(buttonTitle, for: .normal) + self.button.accessibilityLabel = String(format: NSLocalizedString("Pledge %@ a month", comment: ""), price) + self.button.accessibilityValue = String(format: NSLocalizedString("%@ a month", comment: ""), price) + } + else + { + let buttonTitle = NSLocalizedString("Pledge", comment: "") + self.button.setTitle(buttonTitle.uppercased(), for: .normal) + self.button.accessibilityLabel = buttonTitle + self.button.accessibilityValue = buttonTitle + } } else { - let buttonTitle = NSLocalizedString("Pledge", comment: "") + // Free app + + let buttonTitle = NSLocalizedString("Free", comment: "") self.button.setTitle(buttonTitle.uppercased(), for: .normal) - self.button.accessibilityLabel = buttonTitle + self.button.accessibilityLabel = String(format: NSLocalizedString("Download %@", comment: ""), app.name) self.button.accessibilityValue = buttonTitle } - } - else - { - // Free app - let buttonTitle = NSLocalizedString("Free", comment: "") - self.button.setTitle(buttonTitle.uppercased(), for: .normal) - self.button.accessibilityLabel = String(format: NSLocalizedString("Download %@", comment: ""), app.name) - self.button.accessibilityValue = buttonTitle + if let versionDate = app.storeApp?.latestSupportedVersion?.date, versionDate > Date() + { + self.button.countdownDate = versionDate + } + else + { + self.button.countdownDate = nil + } } - if let versionDate = app.storeApp?.latestSupportedVersion?.date, versionDate > Date() - { - self.button.countdownDate = versionDate - } - else - { - self.button.countdownDate = nil - } + // Ensure PillButton is correct size before assigning progress. + self.layoutIfNeeded() } - // Ensure PillButton is correct size before assigning progress. - self.layoutIfNeeded() - if let progress = AppManager.shared.installationProgress(for: app), progress.fractionCompleted < 1.0 { self.button.progress = progress diff --git a/AltStore/Sources/SourcesViewController.swift b/AltStore/Sources/SourcesViewController.swift index 32af98ba..6533c9a3 100644 --- a/AltStore/Sources/SourcesViewController.swift +++ b/AltStore/Sources/SourcesViewController.swift @@ -226,31 +226,33 @@ private extension SourcesViewController let numberOfApps = source.apps.filter { StoreApp.visibleAppsPredicate.evaluate(with: $0) }.count - if let error = source.error - { - let image = UIImage(systemName: "exclamationmark")?.withTintColor(.white, renderingMode: .alwaysOriginal) - - cell.bannerView.button.setImage(image, for: .normal) - cell.bannerView.button.setTitle(nil, for: .normal) - cell.bannerView.button.tintColor = .systemYellow.withAlphaComponent(0.75) - - let action = UIAction(identifier: .showError) { _ in - self.present(error) + UIView.performWithoutAnimation { + if let error = source.error + { + let image = UIImage(systemName: "exclamationmark")?.withTintColor(.white, renderingMode: .alwaysOriginal) + + cell.bannerView.button.setImage(image, for: .normal) + cell.bannerView.button.setTitle(nil, for: .normal) + cell.bannerView.button.tintColor = .systemYellow.withAlphaComponent(0.75) + + let action = UIAction(identifier: .showError) { _ in + self.present(error) + } + cell.bannerView.button.addAction(action, for: .primaryActionTriggered) + cell.bannerView.button.removeAction(identifiedBy: .showDetails, for: .primaryActionTriggered) } - cell.bannerView.button.addAction(action, for: .primaryActionTriggered) - cell.bannerView.button.removeAction(identifiedBy: .showDetails, for: .primaryActionTriggered) - } - else - { - cell.bannerView.button.setImage(nil, for: .normal) - cell.bannerView.button.setTitle(numberOfApps.description, for: .normal) - cell.bannerView.button.tintColor = .white.withAlphaComponent(0.2) - - let action = UIAction(identifier: .showDetails) { _ in - self.showSourceDetails(for: source) + else + { + cell.bannerView.button.setImage(nil, for: .normal) + cell.bannerView.button.setTitle(numberOfApps.description, for: .normal) + cell.bannerView.button.tintColor = .white.withAlphaComponent(0.2) + + let action = UIAction(identifier: .showDetails) { _ in + self.showSourceDetails(for: source) + } + cell.bannerView.button.addAction(action, for: .primaryActionTriggered) + cell.bannerView.button.removeAction(identifiedBy: .showError, for: .primaryActionTriggered) } - cell.bannerView.button.addAction(action, for: .primaryActionTriggered) - cell.bannerView.button.removeAction(identifiedBy: .showError, for: .primaryActionTriggered) } let dateText: String