Sample project -> Содержит последний код
Шаг один:
Найти подвид, который имеет правильную рамку!
Эта небольшая функция вернет фрейм и адрес всех вложенных подзонов.
Мы ищем подраздел, который имеет высоту, которая меньше, чем у UIAlertController
, и имеет Origin
of 0,0
. Рост моего alertController был 128
func subViewStack(view:UIView, levels: [Int]) {
var currentLevels = levels
currentLevels.append(0)
for i in 0..<view.subviews.count {
currentLevels[currentLevels.count - 1] = i
let subView = view.subviews[i]
print(subView.frame, "depth:", currentLevels)
subViewStack(subView, levels: currentLevels)
}
}
Это печатает вещи, как это:
(0.0, 0.0, 270.0, 128.0) depth: [0, 0]
//frame - firstsubview - firstsubview
Это может быть хорошим кандидатом:
(0.0, 0.0, 270.0, 84.0) depth: [0, 1, 0, 0]
//frame - firstsubview - secondsubiew - firstsubview - firstsubview
Это приводит к следующему:
print(alertController.view.subviews[0].subviews[1].subviews[0].subviews[0].frame)
// prints (0.0, 0.0, 270.0, 84.0) -> Bingo!
Шаг два:
Цвет, который подтаблица!
alertController.view.subviews[0].subviews[1].subviews[0].subviews[0].backgroundColor = UIColor.redColor()
Если вы установили цвет перед представлением alertController, он сработает. Установка его в завершение работы Handler.
presentViewController(alertController, animated: true) {() -> Void in
self.subViewStack(alertController.view, levels: [])
print(alertController.view.subviews[0].subviews[1].subviews[0].subviews[0].frame)
alertController.view.subviews[0].subviews[1].subviews[0].subviews[0].backgroundColor = UIColor.redColor()
}
Шаг три:
Сделать это безопасно! Если они когда-либо меняют что-либо в стек, это предотвратит сбой вашего приложения. Ваш взгляд может быть не окрашен, но крушение хуже.
Расширьте UIView, чтобы иметь возможность отображать просмотры с одним из адресов, которые мы напечатали ранее. Используйте guard
или if let
, чтобы предотвратить доступ к несуществующим представлениям.
extension UIView {
// use the printed addresses to access the views. This is safe even if the UIView changes in an update.
func getSubView(withAddress address:[Int]) -> UIView? {
var currentView : UIView = self
for index in address {
guard currentView.subviews.count > index else {
return nil
}
currentView = currentView.subviews[index]
}
return currentView
}
}
Шаг четыре:
Поскольку не допускается к подклассу UIAlertController
мы могли бы попытаться расширить его. Это не даст вам доступ к viewDidAppear
, поэтому вы не сможете отображать анимацию UIAlertController
.
protocol CustomAlert {
var view : UIView! { get }
}
extension CustomAlert {
func titleBackgroundColor(color:UIColor) {
if view == nil {
return
}
if let titleBackground = view.getSubView(withAddress: [0, 1, 0, 0]) {
titleBackground.backgroundColor = color
}
}
}
extension UIAlertController : CustomAlert {
}
Это дает вам как метод, чтобы найти какие-либо подвидов вы можете захотеть изменить и способ добавить пользовательскую функцию для него к этому классу. Без подкласса.
Позвоните, чтобы уточнить цвет titleBackgroundColor
в комплектеHandler presentViewController
.
У вас была возможность посмотреть ответы? –
@RMenke У меня есть решение abhinav, но это не тот ответ, который я ищу. Он изменяет заголовок переднего плана, а не фон – Christoper
Обновленный ответ без подкласса. –