Мне нужно применить градиент глобально к моему статусу и панелям навигации и настроить его должным образом для изменения ориентации.Поскольку я хочу, чтобы это было глобальным, я пытаюсь использовать UIAppearance
.Удивительно, но UIAppearance
не делает это очень легким.
В портретной ориентации он выглядит великолепно, но в альбомной ориентации он слишком высокий, поэтому вы не можете видеть все это:
Вот мой код на данный момент:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let navigationBarAppearance = UINavigationBar.appearance()
navigationBarAppearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
navigationBarAppearance.isTranslucent = false
navigationBarAppearance.tintColor = UIColor.white
let status_height = UIApplication.shared.statusBarFrame.size.height
let gradientLayer = CAGradientLayer(frame: CGRect(x: 0, y: 0, width: 64, height: status_height + 44), colors: [UIColor.init(hex: "005382"), UIColor.init(hex: "00294B")])
let layerImage = gradientLayer.createGradientImage()
navigationBarAppearance.barTintColor = UIColor(patternImage: layerImage ?? UIImage())
}
, и я использую это расширение:
extension CAGradientLayer {
convenience init(frame: CGRect, colors: [UIColor]) {
self.init()
self.frame = frame
self.colors = []
for color in colors {
self.colors?.append(color.cgColor)
}
startPoint = CGPoint(x: 0, y: 0)
endPoint = CGPoint(x: 0, y: 1)
}
func createGradientImage() -> UIImage? {
var image: UIImage? = nil
UIGraphicsBeginImageContext(bounds.size)
if let context = UIGraphicsGetCurrentContext() {
render(in: context)
image = UIGraphicsGetImageFromCurrentImageContext()
}
UIGraphicsEndImageContext()
return image
}
}
Я знаюЯ мог бы проверить ориентацию и затем соответствующим образом изменить градиент, но мне нужно было бы сделать это на каждом контроллере вида, чтобы не использовать цель UIAppearance
и возможность сделать это в одном месте.
Большинство обнаруженных мной потоков SO предоставляют решения для создания градиента верхней панели на уровне контроллера представления, но не на глобальном уровне.
EDIT : пробный ответ от @Pan Surakami onмой UITabBarController
, но у меня все еще есть белые навигационные панели:
Вот моя настройка storybaord:
и код:
class MenuTabBarController: UITabBarController {
var notificationsVM = NotificationsVModel()
var hasNewAlerts: Bool = false
override func viewDidLoad() {
super.viewDidLoad()
setTabs()
styleUI()
notificationsVM.fetchData { (success, newNotifications) in
if success {
self.hasNewAlerts = newNotifications.count > 0 ? true : false
DispatchQueue.main.async {
if let tabBarItems = self.tabBar.items {
for (_, each) in tabBarItems.enumerated() {
if each.tag == 999 { //only update the alerts tabBarItem tag == '999'
self.updateAlertBadgeIcon(self.hasNewAlerts, each)
}
}
}
}
}
}
}
fileprivate func setTabs() {
let tab1 = GradientNavigationController(rootViewController: FeedViewController())
let tab2 = GradientNavigationController(rootViewController: NotificationsTableViewController())
let tab3 = GradientNavigationController(rootViewController: SearchViewController())
let tab4 = GradientNavigationController(rootViewController: ComposeDiscussionViewController())
UITabBarController().setViewControllers([tab1, tab2, tab3, tab4], animated: false)
}
func updateAlertBadgeIcon(_ hasAlerts: Bool, _ item: UITabBarItem) {
if hasAlerts {
item.image = UIImage(named: "alert-unselected-hasAlerts")?.withRenderingMode(UIImage.RenderingMode.alwaysOriginal)
item.selectedImage = UIImage(named: "alert-selected-hasAlerts")?.withRenderingMode(UIImage.RenderingMode.alwaysOriginal)
} else {
hasNewAlerts = false
item.image = UIImage(named: "alert-unselected-noAlerts")?.withRenderingMode(UIImage.RenderingMode.alwaysOriginal)
item.selectedImage = UIImage(named: "alert-selected-noAlerts")?.withRenderingMode(UIImage.RenderingMode.alwaysOriginal)
}
}
// UITabBarDelegate
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
if item.tag == 999 { //alerts tabBarItem tag == '999'
updateAlertBadgeIcon(hasNewAlerts, item)
}
if item.tag == 0 { //Feed Item clicked
if let feedNav = children[0] as? UINavigationController, let feedVC = feedNav.viewControllers[0] as? FeedViewController {
feedVC.tableView.reloadData()
}
}
}
func styleUI() {
UITabBar.appearance().backgroundImage = UIImage.colorForNavBar(color:.lightGrey4)
UITabBar.appearance().shadowImage = UIImage.colorForNavBar(color:.clear)
tabBar.layer.shadowOffset = CGSize.zero
tabBar.layer.shadowRadius = 2.0
tabBar.layer.shadowColor = UIColor.black.cgColor
tabBar.layer.shadowOpacity = 0.30
UITabBarItem.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor : UIColor.grey2,
NSAttributedString.Key.font: UIFont(name: "AvenirNext-DemiBold", size: 12) as Any],
for: .normal)
UITabBarItem.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor : UIColor.darkSapphire,
NSAttributedString.Key.font: UIFont(name: "AvenirNext-DemiBold", size: 12) as Any],
for: .selected)
}
}