[英]"removeFromSuperview" NEVER work on UIApplication?
如何刪除子視圖?
我試圖通過以編程方式創建UIView
和UIImageView
來集成 GIF。
顯示 GIF 效果很好,但是調用隱藏 if 功能時,沒有響應。
下面是兩個函數的代碼。
class CustomLoader: UIView {
static let instance = CustomLoader()
var viewColor: UIColor = .black
var setAlpha: CGFloat = 0.5
var gifName: String = ""
lazy var transparentView: UIView = {
let transparentView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
transparentView.backgroundColor = viewColor.withAlphaComponent(setAlpha)
transparentView.isUserInteractionEnabled = false
return transparentView
}()
lazy var gifImage: UIImageView = {
var gifImage = UIImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 60))
gifImage.contentMode = .scaleAspectFit
gifImage.center = transparentView.center
gifImage.isUserInteractionEnabled = false
gifImage.loadGif(name: gifName)
return gifImage
}()
func showLoaderView() {
self.addSubview(self.transparentView)
self.transparentView.addSubview(self.gifImage)
self.transparentView.bringSubview(toFront: self.gifImage)
UIApplication.shared.keyWindow?.addSubview(transparentView)
}
func hideLoaderView() {
self.transparentView.removeFromSuperview()
}
}
一些想法:
我建議您在hideLoaderView
添加斷點或日志語句,並確保您到達該行。
您應該將此類的init
方法設為private
,以確保您不會在某個單獨的實例上調用hideLoaderView
。 在處理單例時,您要確保不會意外創建另一個實例。
但是我測試了你的代碼,它工作正常。 您的問題可能在於您在何處以及如何調用它(並將init
設為private
,您可能會發現在何處不恰當地使用它)。
在下面的評論中,你說:
我只是簡單地調用函數“CustomLoader().hideLoaderView()” 兩者都在技術上被調用。 “我使用不當的地方”是什么意思?
這就是問題的根源。
CustomLoader().hideLoaderView()
CustomLoader()
的CustomLoader().hideLoaderView()
將創建一個CustomLoader
的新實例,並帶有自己的transparencyView
CustomLoader().hideLoaderView()
等,這正是問題所在。 您並沒有隱藏之前顯示的舊視圖,而是試圖隱藏您剛剛創建但從未顯示過的另一個視圖。
如果您改為使用該static
,例如CustomLoader.instance.showLoaderView()
和CustomLoader.instance.hideLoaderView()
,那么問題就會消失。 然后,您將隱藏之前顯示的相同視圖。
順便說一下,其他一些不相關的觀察:
如果這是一個單例或共享實例,則約定將調用該static
屬性shared
,而不是instance
。
順便說一句,您沒有將此CustomLoader
用作UIView
,因此我不會將其設為UIView
子類。 不要讓它成為任何東西的子類。
顯然,您也會消除那條self.addSubview(transparentView)
行。
bringSubview(toFront:)
調用是不必要的。
你應該避免引用UIScreen.main.bounds
。 你不知道你的應用程序是否可能處於多任務模式(也許現在這不是問題,但這是一種不必要的假設,會在以后導致問題)。 只需參考您將其添加到的UIWindow
的bounds
即可。 您還應該在顯示此視圖時更新此frame
,而不是在創建它時(以防您在此期間更改了方向,或其他任何情況)。
順便說一句,在 iOS 13 及更高版本中不鼓勵使用keyWindow
,因此您可能最終也想刪除它。
添加gifImage
(我建議將其重命名為gifImageView
因為它是圖像視圖,而不是圖像),您不應引用其超級視圖的center
。 這是透明視圖在其超級視圖坐標系中的坐標,它可能與透明視圖自身的坐標系完全不同。 在這種情況下,它恰好可以工作,但它暗示了對視圖坐標系的根本誤解。 引用transparentView
的bounds
,而不是它的center
。
如果您要公開viewColor
和setAlpha
,則至少應該將transparentView
的顏色設置從lazy
初始值設定項中提取到showLoaderView
。 現在,如果您顯示加載程序一次,然后更改顏色,並嘗試再次顯示它,您將看不到新顏色。
同樣的問題也適用於 gif 圖像。 所以,我didSet
其didSet
觀察者。
因此,將所有這些放在一起:
class CustomLoader{
static let shared = CustomLoader()
private init() { }
var dimmingColor: UIColor = .black
var dimmingAlpha: CGFloat = 0.5
var gifName: String = "" { didSet { gifImage.loadGif(name: gifName) } }
lazy var transparentView: UIView = {
let transparentView = UIView()
transparentView.isUserInteractionEnabled = false
return transparentView
}()
lazy var gifImageView: UIImageView = {
var gifImage = UIImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 60))
gifImage.contentMode = .scaleAspectFit
gifImage.isUserInteractionEnabled = false
return gifImage
}()
func showLoaderView() {
guard let window = UIApplication.shared.keyWindow else { return }
transparentView.frame = window.bounds
transparentView.backgroundColor = dimmingColor.withAlphaComponent(dimmingAlpha)
gifImageView.center = CGPoint(x: transparentView.bounds.midX, y: transparentView.bounds.midY)
transparentView.addSubview(gifImageView)
window.addSubview(transparentView)
}
func hideLoaderView() {
transparentView.removeFromSuperview()
}
}
為什么在擁有 CustomLoader 實例視圖時使用透明視圖
嘗試使用這個
class CustomLoader: UIView {
static let instance = CustomLoader()
var viewColor: UIColor = .black
var setAlpha: CGFloat = 0.5
var gifName: String = ""
init() {
super.init(frame: UIScreen.main.bounds)
backgroundColor = viewColor.withAlphaComponent(setAlpha)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
lazy var gifImage: UIImageView = {
var gifImage = UIImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 60))
gifImage.backgroundColor = .red
gifImage.contentMode = .scaleAspectFit
gifImage.center = center
gifImage.isUserInteractionEnabled = false
gifImage.loadGif(name: gifName)
return gifImage
}()
func showLoaderView() {
addSubview(self.gifImage)
UIApplication.shared.keyWindow?.addSubview(self)
}
func hideLoaderView() {
removeFromSuperview()
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.