SFSafariViewController нет темного режима с настраиваемым цветом оттенка панели

#ios #swift #sfsafariviewcontroller #ios-darkmode

#iOS #swift #sfsafariviewcontroller #ios-darkmode

Вопрос:

Я вызываю SFSafariViewController из своего приложения, чтобы открыть myurl . Я изменил цвет оттенка панели SFSafariViewController . Это отлично работает с использованием:

 vc.preferredBarTintColor = UIColor.teal025
 

Однако, когда устройство меняет режим стиля внешнего вида со светлого на темный, цвет оттенка полосы остается teal025 и не настраивается на более темный цвет, как это делает цвет оттенка полосы по умолчанию (например, светло-серый на темно-серый), если он не установлен с помощью preferredBarTintColor .

Основные части приложения также используют teal025 в качестве цвета оттенка панели навигации. Эти объекты автоматически настраивают цвет по желанию при входе в темный режим.

Как я могу добиться такого же поведения для цвета оттенка панели SFSafariViewController?

Здесь весь код:

 let urlString = "https://myurl"
if let url = URL(string: urlString) {
    let vc = SFSafariViewController(url: url)
    vc.preferredBarTintColor = UIColor.teal025 // this prevents dark mode change
    vc.preferredControlTintColor = UIColor.teal100
    present(vc, animated: true)
}
 

NB1: я не хочу использовать UIWebView , поскольку myurl использует шрифты Google, которые не отображаются должным образом при использовании iOS UIWebView .

NB2: teal025 и teal100 являются настраиваемыми цветами.

— ОБНОВЛЕНИЕ — (10.01.2021)

Как и было запрошено, вот как я определяю (d) свои цвета.

 extension UIColor {
    static var teal025: UIColor { return UIColor(red: 0.0, green: 127.0/255.0, blue: 127.0/255.0, alpha: 1.0) } // 0x008080
}
 

— ОБНОВЛЕНИЕ — (12.01.2021)

Моя цель — иметь оттенок панели SFSafariViewController, который имеет точно такие же цветовые оттенки, градиент и прозрачность, чем панель навигации приложения. Моя навигация Prefer Large Titles — это стиль ввода вместе с scrollEdgeAppearance . Эти два свойства обрабатывают автоматические изменения предпочтений светлого / темного, а также прозрачность и вертикальные цветовые градиенты. Я считаю, что в SFSafariViewController нет положений для всего этого. Таким образом, самым близким будет инициализатор dynamicProvider UIColor, предложенный CSmith. Это будет «только» для изменения предпочтений светлого / темного.

 let urlString = "https://myurl"
if let url = URL(string: urlString) {
    let vc = SFSafariViewController(url: url)
    vc.preferredBarTintColor = UIColor.safariBarTint
    vc.preferredControlTintColor = UIColor.safariControlTint
    present(vc, animated: true)
}

extension UIColor {
    struct Material {
        static var orangeA100: UIColor { return UIColor(red: 0xff / 0xff,
                                                        green: 0xd1 / 0xff,
                                                        blue:  0x80 / 0xff,
                                                        alpha: 1.0) } // #FFD180
        ...
        static var orangeA700: UIColor { return UIColor(red: 0xff / 0xff,
                                                        green: 0x6d / 0xff,
                                                        blue:  0x00 / 0xff,
                                                        alpha: 1.0) } // #FF6D00
    }
}

static var safariBarTint: UIColor {
    if #available(iOS 13.0, *) {
        return UIColor { (traits: UITraitCollection) -> UIColor in
            return traits.userInterfaceStyle == .dark ?
                UIColor.Material.orangeA700 :
                UIColor.Material.orangeA100
        }
    } else { // for iOS 12 and earlier
        return UIColor.Material.orangeA100
    }
}
static var safariControlTint: UIColor {
    if #available(iOS 13.0, *) {
        return UIColor { (traits: UITraitCollection) -> UIColor in
            return traits.userInterfaceStyle == .dark ?
                UIColor.Material.orangeA100 :
                UIColor.Material.orangeA700
        }
    } else { // for iOS 12 and earlier
        return UIColor.Material.orangeA700
    }
}
 

Я считаю, что цветовая адаптация 1: 1 между панелью навигации приложения и SFSafariViewController должна выполняться вручную, следовательно, остается выстрел в темноте ?!

Я считаю, что приведенный выше код является самым близким, который я могу получить.

Ответ №1:

Я наблюдаю SFSafariViewController за надлежащим соблюдением светлых и темных вариантов UIColor набора как preferredBarTintColor . Ваше определение teal025 в расширении UIColor определяет один вариант цвета (0x008080) и не имеет отдельного цвета темного режима.

Для разрешения определите свой teal025 в каталоге цветовых ресурсов и загрузите значение с помощью:

preferredBarTintColor = UIColor.init(named:"teal025")

Убедитесь, что в цветовом ресурсе определены как темные, так и светлые варианты, выбрав «Любой, темный» для настройки Appearance , затем установите соответствующие цвета для каждого.

Или используйте инициализатор dynamicProvider UIColor, чтобы возвращать варианты темного и светлого режимов во время выполнения, что-то вроде этого:

 extension UIColor 
{
    static var teal025: UIColor 
    {
        if #available(iOS 13.0, *) 
        {
            return UIColor { (traits: UITraitCollection) -> UIColor in
                
                // Return one of two colors depending on light or dark mode
                return traits.userInterfaceStyle == .dark ?
                    UIColor(red: 0.0, green: 0.5, blue: 0.5, alpha: 1) :
                    UIColor(red: 0.0, green: 0.4, blue: 0.4, alpha: 1)
            }
        } 
        else 
        {
            // for iOS 12 and earlier
            return UIColor(red: 0.0, green: 0.5, blue: 0.5, alpha: 1)
        }
    }
}
 

Наконец, и после лучшего понимания вашего вопроса, вы, возможно, понимаете, что SFSafariViewController цвет оттенка полосы отличается от вашего приложения из-за прозрачности полосы. В настоящее время нет возможности получить доступ к UINavigationBar оф SFSafariViewController , чтобы отключить прозрачность.

Комментарии:

1. Ваш код работает. Однако у меня (вероятно, по ошибке) создалось «впечатление», что даже пользовательские UIColors будут автоматически меняться при переходе из светлого в темный режим, как это делают оттеночные цвета, определенные в раскадровке. Разве невозможно определить UIColor в коде, который делает именно это автоматически (ваш код делает это, но вручную)? Если нет, то как я могу определить (сгенерированные системой) значения RGB для цвета темного режима с учетом определенного цвета светового режима?

2. Я отредактировал свой ответ, чтобы показать каталог цветовых ресурсов в качестве предпочтительного подхода, это будет обрабатывать автоматическое обновление, когда пользователь изменяет настройку темного / светлого режима устройства

3. Пожалуйста, также обратите внимание, что не существует такого понятия, как «системные значения RGB для цвета темного режима, заданные определенным цветом светового режима». Вы можете решить, что teal025 всегда равен 0x008080 как в темном, так и в светлом режимах, или слегка изменить значения RGB для лучшего внешнего вида.

4. Вы говорите, что предпочтительнее подход к каталогу активов, поскольку он автоматически обрабатывает изменения, когда пользователь меняет предпочтения светлого / темного. Теперь я использовал предложенное вами расширение UIColor code, и оно также вносит желаемые изменения в пользовательский интерфейс, как только изменяется предпочтение light / dark. Другими словами … В этом отношении я не вижу разницы между каталогом активов и расширением UIColor code.

5. к сожалению , свойство NavigationController SFSafariViewController, похоже, равно нулю, поэтому вы не можете получить доступ к панели навигации, чтобы делать такие вещи, как отключение прозрачности, по крайней мере, я не знаю о iOS 14