快速更改所有视图控制器背景

时间:2019-01-18 11:31:09

标签: ios swift

我正在我的项目应用程序上工作,我想允许我的用户将背景墙纸更改为在所有屏幕上都相同。我有一个要添加的设置屏幕。我已将ImageViews添加到所有视图控制器,并且我具有一些具有UIscrollview的视图控制器,因此我将Imageview添加到了幻灯片模板。现在,我的难题是如何允许用户选择预览壁纸,以便它更改每个视图控制器上的Imageview图像。我已经创建了如下所示的@IBOutlets。

@IBOutlet weak var slideBackground: UIImageView!
@IBOutlet weak var homeScreenBackground: UIImageView!
@IBOutlet weak var settingsBackground: UIImageView!

2 个答案:

答案 0 :(得分:2)

您应该使用系统范围的NotificationCenter

简单地说,您可以将对象 subscribe 设置为默认的NotificationCenter,并指定在发布通知时执行的选择器(方法)。

您还可以发布代表墙纸更换事件的自定义通知。

我已在为实现系统范围的“暗模式”转换而构建的应用中使用了此功能。

要发布:

@objc func postWallpaperChangeNotification() {
    NotificationCenter.default.post(name: .wallpaperChanged, object: nil)
}

要订阅:

    NotificationCenter.default.addObserver(self, selector: #selector(someMethodToRunWhenWallpaperChanges(_:)), name: . wallpaperChanged, object: nil)

您还需要删除deinit()中的观察者。

这是大概的代码,可以给您增添一点趣味。

答案 1 :(得分:0)

您有几种选择。.哪种选择最好取决于您的需求。

正如伍德斯托克在他的回答中提到的那样,您可以使用NotificationCentre,我不会再对此进行解释。

另一种选择是将图像名称存储在要用于背景图像的UserDefaults中。

任何时候更改背景...设置值

 UserDefaults.standard.set(imageName, forKey "backgroundImageName")

然后在每个视图控制器中,只需将值加载到viewWillAppear

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated: animated)
    if let backgroundImageName = UserDefaults.standard.string(forKey: "backgroundImageName") {
        self.backgroundImageView.image = UIImage(named: backgroundImageName)
    }
}

虽然这两个选项都不容易进行单元测试。您可以使用Mocks进行测试。

此方法的一个好处是,它可以“记住”用户重新启动应用程序之间的设置。

有关如何使用子类减少代码重复的示例:

class WallpaperedViewController: UIViewController {

    lazy private var imageView: UIImageView = {
        let imageView = UIImageView()
        view.addSubview(imageView)
        view.sendSubview(toBack: imageView)
        return imageView
    }()

    private func setWallPaperImage() {
        let imageName = UserDefaults.standard.string(forKey: "backgroundImageName")

        let image = UIImage(named: imageName!)
        imageView.image = image
        //imageView.contentMode = .scaleAspectFill


        imageView.translatesAutoresizingMaskIntoConstraints = false
        imageView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        imageView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        imageView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        imageView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)

        self.setWallPaperImage()
    }
}

然后为每个具有此背景图像墙纸的ViewController扩展此类:

class SomeViewController: WallpaperedViewController {}