Navigation bar text color is not updating
Hi, Earlier I am using iOS SDK 16.12.0 now I have to update the SDK to 18.14.2. There is a lots of configuration get updated. Now I am not able to update navigation bar background colour or text colour. It says use MessageCenterViewStyle methods. I have implemented custom view style
struct CustomMessageCenterViewStyle: MessageCenterViewStyle { @ViewBuilder func makeBody(configuration: Configuration) -> some View { if #available(iOS 16.0, *) { NavigationStack { configuration.content .navigationViewStyle(.automatic) .navigationBarTitleDisplayMode(.inline) .navigationTitle(Text("Custom Message Center").foregroundColor(.white)) .toolbarBackground(.blue, for: .navigationBar) .toolbarBackground(.visible, for: .navigationBar) .toolbarColorScheme(configuration.colorScheme) } } else { NavigationView { configuration.content .navigationTitle(Text("Old Custom Message Center").foregroundColor(.white)) .navigationBarTitleDisplayMode(.large) } .navigationViewStyle(.stack) } } }
and assigned this style like this MessageCenterView() .messageCenterViewStyle( CustomMessageCenterViewStyle() )
But I didn't see any navigation colour get changes. Please help me if I am doing some mistake.
Thank You! Abichal
@Abichaljha1993 I'm able to get our example to work without any issues:
struct CustomMessageCenterViewStyle: MessageCenterViewStyle {
@ViewBuilder
func makeBody(configuration: Configuration) -> some View {
if #available(iOS 16.0, *) {
NavigationStack {
configuration.content
.navigationBarTitleDisplayMode(.inline)
.navigationTitle(Text("Custom Message Center"))
.toolbarBackground(.mint, for: .navigationBar)
.toolbarBackground(.visible, for: .navigationBar)
.toolbarColorScheme(configuration.colorScheme)
}
} else {
NavigationView {
configuration.content
.navigationTitle(Text("Old Custom Message Center"))
.navigationBarTitleDisplayMode(.large)
}
.navigationViewStyle(.stack)
}
}
}
MessageCenterView()
.messageCenterViewStyle(
CustomMessageCenterViewStyle()
)
Is it possible you are testing on <iOS 15 or overriding the navigation bar appearance globally somewhere in your code? Does your navigation title say "Old Custom Message Center"?
Hi David, My application is written in Swift UIKit and previously I am using SDK 14 now we are facing some UI issue on OS 18 content is going inside the navigation bar. Now I am trying to update it to SDK 18. Here I am not able to see "Old Custom Message Center" or new It display "Message Center" if I am not providing any text to theme. Let me share you my existing code so that you can correct me where I am doing any mistake.
`class UrbanAirshipManager: NSObject {
private override init() {}
/// shared instance of urbanAirShip
static let sharedInstance = UrbanAirshipManager()
static var returnUnreadCount: (() -> Void)?
func isPushNotificationEnabled(completionHandler: @escaping (Bool) -> Void) {
UNUserNotificationCenter.current().getNotificationSettings { settings in
DispatchQueue.main.async {
if settings.authorizationStatus == .authorized || settings.authorizationStatus == .provisional {
completionHandler(true && UIApplication.shared.isRegisteredForRemoteNotifications)
} else {
completionHandler(false)
}
}
}
}
/// configure airship for application.
@MainActor func configureAirship(isEnable: Bool?) {
let config = AirshipConfig.config()
if ServiceConstant.BaseURLConstant.productionBaseUrl == PRODUCTION {
// configuration with key
} else {
// configuration with key
}
config.inProduction = true
config.detectProvisioningMode = true
config.messageCenterStyleConfig = "UAMessageCenterDefaultStyle"
config.urlAllowList = ["*"]
// Call takeOff (which creates the UAirship singleton)
Airship.takeOff(config, launchOptions: nil)
Airship.privacyManager.enabledFeatures = [.push, .tagsAndAttributes, .messageCenter, .analytics]
Airship.deepLinkDelegate = self
Airship.push.userPushNotificationsEnabled = isEnable ?? self.isNotificationEnabled()
Airship.push.defaultPresentationOptions = [.sound]
Airship.privacyManager.enableFeatures(AirshipFeature.contacts)
Airship.push.pushNotificationDelegate = self
Airship.push.backgroundPushNotificationsEnabled = true
configureMessageCenter()
MessageCenter.shared.predicate = CustomPredicate()
AppSyncHelper.syncLippChannel(withoutTimestamp: true)
}
/// is notification enabled
func isNotificationEnabled() -> Bool {
return Airship.push.userPushNotificationsEnabled
}
/// change notificarion setting
/// - Parameter isEnabled: isEnabled description
func setPushNotification(isEnabled: Bool) {
Airship.push.userPushNotificationsEnabled = isEnabled
}
/// configure and open messgae center
func openMessageCenter() {
DispatchQueue.main.async {
MessageCenter.shared.display()
AnalyticsManager.shared.logEvent(event: .screenMessageCenter)
AnalyticsManager.shared.logScreenViewEvent(event: .screenMessageCenter, className: String(describing: type(of: self)))
}
}
func dismissMessageCenter(isFromBanner: Bool = false) {
DispatchQueue.main.async {
let keyWindow = UIApplication.shared.windows.filter {$0.isKeyWindow}.first
guard let topController = keyWindow?.rootViewController else { return }
if (topController.presentedViewController as? RegistrationReminderController) != nil {
regReminderController: while let reminderController = topController.presentedViewController as? RegistrationReminderController {
reminderController.dismiss(animated: false)
break regReminderController
}
if isFromBanner {
MessageCenter.shared.dismiss()
}
} else {
MessageCenter.shared.dismiss()
}
}
}
func countOfUnreadMessage() async -> Int {
await MessageCenter.shared.inbox.refreshMessages()
return await MessageCenter.shared.inbox.messages.filter({$0.extra["conferenceCode"] == defaultConfCode}).count
}
/// style message center
@MainActor func configureMessageCenter() {
var theme = MessageCenterTheme()
theme.navigationBarTitle = "notifications".getLocalizedString()
theme.messageListContainerBackgroundColor = Color(currentTheme.marine)
theme.messageViewContainerBackgroundColor = Color(currentTheme.marine)
theme.cellTitleColor = Color(currentTheme.marine)
theme.cellTitleFont = Font(currentTheme.getCustomSizeSemiBoldFont(16))
theme.cellDateFont = Font(currentTheme.bodytextSize13Regular)
theme.cellDateColor = Color(currentTheme.marine)
theme.editButtonTitleColor = .white
theme.backButtonColor = .white
theme.deleteButtonTitleColor = .white
theme.unreadIndicatorColor = Color(currentTheme.lipstick)
// Set the theme on the default Message Center
MessageCenter.shared.theme = theme
/// This line of code not executing properly. MessageCenterView() .messageCenterViewStyle( CustomMessageCenterViewStyle() ) }
/// get channel identifier
func getChannelIdentifier() -> String {
return Airship.channel.identifier ?? ""
}
/// Check Airship is configure or not
func isAirshipConfigure() -> Bool {
return Airship.isFlying
}
/// Un-register the application from airship to receive push.
func dereigsterFromAirship() {
Airship.push.userPushNotificationsEnabled = false
}
}
extension UrbanAirshipManager: DeepLinkDelegate { func receivedDeepLink(_ url: URL, completionHandler: @escaping () -> Void) { DispatchQueue.main.async { [weak self] in deeplinker.handleDeeplink(url: url) self?.dismissMessageCenter() } } func receivedDeepLink(_ deepLink: URL) async { DispatchQueue.main.async { [weak self] in deeplinker.handleDeeplink(url: deepLink) self?.dismissMessageCenter() } } }
class CustomPredicate: MessageCenterPredicate { func evaluate(message: MessageCenterMessage) -> Bool { // return message.extra["conferenceCode"] == defaultConfCode return true } }
struct CustomMessageCenterViewStyle: MessageCenterViewStyle { @ViewBuilder func makeBody(configuration: Configuration) -> some View { if #available(iOS 16.0, *) { NavigationStack { configuration.content .navigationViewStyle(.automatic) .navigationBarTitleDisplayMode(.inline) .navigationTitle(Text("Custom Message Center").foregroundColor(.white)) .toolbarBackground(.blue, for: .navigationBar) .toolbarBackground(.visible, for: .navigationBar) .toolbarColorScheme(configuration.colorScheme) } } else { NavigationView { configuration.content .navigationTitle(Text("Old Custom Message Center").foregroundColor(.white)) .navigationBarTitleDisplayMode(.large) } .navigationViewStyle(.stack) } } }`
The line of code you commented on Is creating the SwiftUI MessageCenterView then doing nothing with it:
/// This line of code not executing properly.
MessageCenterView()
.messageCenterViewStyle(
CustomMessageCenterViewStyle()
)
You need to display the view itself.
For example - take a look at how the Sample app displays the MessageCenterView in its parent view AppView:
/* Copyright Urban Airship and Contributors */
import AirshipCore
import AirshipMessageCenter
import AirshipPreferenceCenter
import AirshipDebug
import SwiftUI
struct AppView: View {
@EnvironmentObject var appState: AppState
@State var shakeCount: Int = 0
var body: some View {
TabView(selection: $appState.selectedTab) {
HomeView()
.tabItem {
Label(
"Home",
systemImage: "house.fill"
)
}
.onAppear {
Airship.analytics.trackScreen("home")
}
.tag(SampleTabs.home)
MessageCenterView()
.messageCenterViewStyle(
CustomMessageCenterViewStyle()
)
.tabItem {
Label(
"Message Center",
systemImage: "tray.fill"
)
}
.badge(self.appState.unreadCount)
.onAppear {
Airship.analytics.trackScreen("message_center")
}
.tag(SampleTabs.messageCenter)
PreferenceCenterView(
preferenceCenterID: MainApp.preferenceCenterID
)
.navigationViewStyle(.stack)
.tabItem {
Label(
"Preferences",
systemImage: "person.fill"
)
}
.onAppear {
Airship.analytics.trackScreen("preference_center")
}
.tag(SampleTabs.preferenceCenter)
#if canImport(AirshipDebug)
debug.tabItem {
Label(
"Debug",
systemImage: "gear"
)
}
.onAppear {
Airship.analytics.trackScreen("debug")
}
.tag(SampleTabs.debug)
#endif
}
.onShake {
shakeCount += 1
let event = CustomEvent(name: "shake_event", value: Double(shakeCount))
event.track()
AppState.shared.toastMessage = Toast.Message(
text: "Tracked custom event: shake_event",
duration: 2.0
)
}
.overlay(makeToastView())
}
@ViewBuilder
private func makeToastView() -> some View {
Toast(message: self.$appState.toastMessage)
.padding()
}
#if canImport(AirshipDebug)
@ViewBuilder
var debug: some View {
if #available(iOS 16.0, *) {
NavigationStack {
ZStack{
AirshipDebugView()
}
}
} else {
NavigationView {
AirshipDebugView()
}
.navigationViewStyle(.stack)
}
}
#endif
}
struct AppView_Previews: PreviewProvider {
static var previews: some View {
AppView()
}
}
This is swift UI. But my application is in UIKIT. How can I achieve this is UIKit? SDK didn't expose navigation to customise, like message container view background colour detail view cell colour etc. are expose so we can customise it using UIKit applocation.
SwiftUI views can be used inside UIKit with UIHostingViewControllers. That way you can customize it however you like in SwiftUI using the style overrides we discussed while still retaining the ability to embed the view in a UIKit app. Here's a quick example of creating a UIKit-compatible message center called MyMessageCenterView that's customized:
class MyMessageCenterView: UIViewController {
override func viewDidLoad() {
super.viewidLoad()
let swiftUIView = MessageCenterView()
.messageCenterViewStyle( CustomMessageCenterViewStyle() ) /// Customize here
let host = UIHostingController(rootView: swiftUIView)
addChild(host)
host.view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(host.view)
NSLayoutConstraint.activate([
host.view.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
host.view.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor),
host.view.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor),
host.view.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor),
])
host.didMove(toParent: self)
}
}
struct CustomMessageCenterViewStyle: MessageCenterViewStyle {
@ViewBuilder
func makeBody(configuration: Configuration) -> some View {
if #available(iOS 16.0, *) {
NavigationStack {
configuration.content
.navigationBarTitleDisplayMode(.inline)
.navigationTitle(Text("Custom Message Center"))
.toolbarBackground(.mint, for: .navigationBar)
.toolbarBackground(.visible, for: .navigationBar)
.toolbarColorScheme(configuration.colorScheme)
}
} else {
NavigationView {
configuration.content
.navigationTitle(Text("Old Custom Message Center"))
.navigationBarTitleDisplayMode(.large)
}
.navigationViewStyle(.stack)
}
}
}