我正在尝试第一次使用委托和协议。
我想在许多视图控制器中更改主题。
然后在任何具有更改主题协议的控制器上
当我现在转到此控制器时,我希望主题是新的但旧的。
我不会从主题控制器转到它们已更改的地方
我的代码
protocol ThemeDelegate: class {
func changeTheme(theme: UIColor)
}
class FirstController: UICollectionViewController, UICollectionViewDelegateFlowLayout, ThemeDelegate {
var newTheme: UIColor = .red
func changeTheme(theme: UIColor) {
newTheme = theme
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = newTheme
}
}
ThemeController {
weak var themeDelegate: ThemeDelegate?
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let theme = .blue
themeDelegate?.changeTheme(theme: theme)
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: themeCellId, for: indexPath) as! ThemeCell
cell.themeImageView.image = UIImage(named: "theme cell image")
return cell
}
}
答案 0 :(得分:1)
我将尝试使其简单:-
1)首先,声明一个协议:-
protocol ThemeDelegate{
func changeTheme(theme: String, fontColor: UIColor, alpha: CGFloat)
}
2)在ThemeController中具有该协议的变量:
open var themeDelegate: ThemeDelegate? = nil
3)通过themeDelegate
调用委托函数:-(直到这一步为止,您都已完成此操作)
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
themeDelegate?.changeTheme(theme: theme, fontColor: fontColor, alpha: alpha)
}
4)您需要像AnyController
一样将yourThemeControllerInstance.delegate = self
用作委托人,并且您也已经做到了。
该操作无效,因为您已声明ThemeController
的新实例,并已符合AnyController
是该新实例的委托,该新实例具有相同的旧主题:< / strong>
override func viewDidLoad() {
let themeController = ThemeController() // This is a new instance which you have created, so gets initialised with old theme. You have made your class to be the delegate of this instance
themeController.themeDelegate = self
}
为使您的代表按预期工作,您需要使用ThemeController
的同一实例来更改主题
答案 1 :(得分:1)
您可以设置委托,但需要加载仔细的视图。
您也可以使用通知进行此操作,并发送所有符合主题的viewControllers
1-您的步骤
import UIKit
protocol ThemeDelegate: class {
func changeTheme(theme: String, fontColor: UIColor, alpha: CGFloat)
}
class ThemeController: UIViewController {
weak var themeDelegate: ThemeDelegate?
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
themeDelegate?.changeTheme(theme: theme, fontColor: fontColor, alpha: alpha)
}
}
class XViewController: UIViewController {
// Create an instance
lazy var themeController = ThemeController()
override func viewDidLoad() {
super.viewDidLoad()
// We need call loadView becase collectionView needs to be show
themeController.loadView()
themeController.themeDelegate = self
}
}
extension XViewController: ThemeDelegate {
// And we conform ThemeDelegate
func changeTheme(theme: String, fontColor: UIColor, alpha: CGFloat) {
// TODO UI
}
}
2-观察者步骤
// Sometimes we need update multiple viewControllers and we should use notification and observers
// We create a model
struct Theme {
let theme: String
let fontColor: UIColor
let alpha: CGFloat
}
// We need a protocol for we don't want all view controller listen theme
protocol Themeable: class {
func listenTheme()
func didThemeChange(theme: Theme)
}
// Global notification name
let themeableNotificationName = Notification.Name(rawValue: "ThemeableNotification")
// Our protocol extension and observer notification
extension Themeable where Self: UIViewController {
func listenTheme() {
NotificationCenter.default.addObserver(forName: themeableNotificationName, object: nil, queue: nil) { [weak self] notification in
guard let theme = notification.object as? Theme else { return }
self?.didThemeChange(theme: theme)
}
}
}
// Notification sender themeController
class NotifyThemeController: UIViewController {
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
// Create a model and post
NotificationCenter.default.post(name: themeableNotificationName, object: Theme(theme: "Lorem", fontColor: .red, alpha: 1.0), userInfo: nil)
}
}
// YViewController
class YViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// We need call this method for observer
listenTheme()
}
}
// YViewController conforms Themeable
extension YViewController: Themeable {
func didThemeChange(theme: Theme) {
// TODO UI
}
}
// ZViewController
class ZViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// We need call this method for observer
listenTheme()
}
}
// ZViewController conforms Themeable
extension ZViewController: Themeable {
func didThemeChange(theme: Theme) {
// TODO UI
}
}
玩得开心!