离开它时如何从一个 ViewController 上的 UIView 子视图中处理
How to dispose from UIView subviews on one ViewController when navigating away from it
我开始学习 Swift 并决定构建一个没有故事板的应用程序。
我的 SceneDelegate scene
函数实例化一个 TabBarController
window = UIWindow(frame: UIScreen.main.bounds)
let tb = TabBarController()
window?.rootViewController = tb
window?.makeKeyAndVisible()
window?.windowScene = windowSceme
我有一个从 UITabBarController 扩展而来的 TabBarController,它几乎为选项卡栏设置了样式
对于 Tabbar 的每个项目,我都有一个 ViewController。出于这个问题的目的,我将指定第一个“Home”。
在扩展 ViewController 的主页中,我有以下内容
let homePageView = HomePageView()
override func viewWillLayoutSubviews() {
navigationController?.isNavigationBarHidden = true
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
homePageView.setupHomePage()
view.addSubview(homePageView)
}
override func viewWillDisappear(_ animated: Bool) {
homePageView.dispose()
}
控制器几乎只负责调用主要组件 HomePageView()
中将要显示在屏幕上的任何内容。最后,还有两个观点。一个旋转木马 HomePageCarrousel()
和一个 header HomePageSocialUp()
。此视图实例化后两个引用并以编程方式设置布局并将它们添加为子视图。它还包括一个将实例化的 类 设置为 nil 的处置函数,例如 --> Instantiate - homePageCarrousel = HomePageCarrousel()
并且处置函数具有 homePageCarrousel = nil
这很好用,但是当我通过标签栏导航离开当前视图控制器并导航回它时,现在我在 [=23] 中有两个 HomePageCarrousel()
和 HomePageSocialUp()
实例=]
我可能在某处持有一个强有力的参考,但我不知道什么时候。有人可以指出我应该在哪里调试它或者可能是什么导致了问题。
我还提供了复制的两个视图的代码,以防出现问题
HomePageSocialUp
class HomePageSocialUp: UIView {
let logo = UIImage(named: "LogoSmiles")
let socialImages: [UIImage] = [UIImage(named: "tripadvisor")!, UIImage(named: "instagram")!, UIImage(named: "facebook")!, UIImage(named: "linkedin")!]
func setupHeaderCircle() {
guard let insetTop = UIApplication.shared.keyWindow?.safeAreaInsets.top else {return}
let circlePath = UIBezierPath(arcCenter: CGPoint(x: UIScreen.main.bounds.width / 2, y: insetTop + 60), radius: CGFloat(90), startAngle: CGFloat(0), endAngle: CGFloat(Double.pi * 2), clockwise: true)
let shapeLayer = CAShapeLayer()
shapeLayer.path = circlePath.cgPath
shapeLayer.fillColor = UIColor.white.cgColor
layer.addSublayer(shapeLayer)
}
func setupSocialHeader() {
setupHeaderCircle()
layer.masksToBounds = true;
backgroundColor = UIColor.TintColor
layer.shadowColor = UIColor.lightGray.cgColor
layer.shadowOpacity = 0.8
layer.shadowOffset = CGSize(width: 0.0, height: 0.0)
layer.shadowRadius = 3.0
layer.masksToBounds = false
frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 280)
let imageView = UIImageView()
guard let logo = logo else {return}
guard let insetTop = UIApplication.shared.keyWindow?.safeAreaInsets.top else {return}
imageView.frame = CGRect(x: CGFloat(Int((UIScreen.main.bounds.width - (logo.size.width)))) / 2, y: 120 - (logo.size.width / 2), width: logo.size.width, height: logo.size.height)
imageView.image = logo
addSubview(imageView)
}
}
HomePageCarrousel
class HomePageCarrousel: UIScrollView {
var images: [UIImage]?
var originX = 0
var numberOfIterations = 0
var timer: Timer?
func setupCarrousel() {
let x = (Int(UIScreen.main.bounds.width) - (Int(UIScreen.main.bounds.width) - 60)) / 2
frame = CGRect(x: x, y: (Int(frame.origin.y) - 350) / 2, width: Int(UIScreen.main.bounds.width) - 60, height: 350)
let newImage = textToImage(drawText: "Creating Smiles in unique places.", frame: frame, inImage: UIImage(named: "smiles1")!, atPoint: CGPoint(x: frame.origin.x + 20, y: frame.height - 20))
images = [newImage, UIImage(named: "smiles2")!]
guard timer == nil else { return }
timer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(startScrolling), userInfo: nil, repeats: true)
guard let imageCount = images?.count, let images = images else { return }
contentSize = CGSize(width: frame.width * CGFloat(images.count), height: frame.height)
for image in 0..<imageCount {
let imageView = UIImageView()
imageView.image = images[image]
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
let xPosition = frame.width * CGFloat(image)
imageView.frame = CGRect(x: xPosition, y: 0, width: frame.width, height: frame.height)
addSubview(imageView)
}
timer?.fire()
}
func textToImage(drawText text: String, frame: CGRect, inImage image: UIImage, atPoint point: CGPoint) -> UIImage {
let textColor = UIColor.white
let textFont = UIFont(name: "Helvetica Bold" , size: 12)!
let scale = UIScreen.main.scale
UIGraphicsBeginImageContextWithOptions(image.size, false, scale)
let textFontAttributes = [
NSAttributedString.Key.font: textFont,
NSAttributedString.Key.foregroundColor: textColor,
] as [NSAttributedString.Key : Any]
image.draw(in: CGRect(origin: CGPoint.zero, size: image.size))
text.draw(in: frame, withAttributes: textFontAttributes)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
@objc func startScrolling() {
print(originX)
guard let images = images else { return }
if originX == images.count {
originX = 0
numberOfIterations += 1
}
if numberOfIterations > 2 {
timer?.invalidate()
timer = nil
numberOfIterations = 0
}
let x = CGFloat(originX) * frame.size.width
setContentOffset(CGPoint(x: x, y: 0), animated: true)
originX += 1
}
}
在此先致谢
您是否尝试删除子视图,例如
homePageView.subviews.forEach { (view) in
//taking appropriate action to whichever view you want
view.removeFromSuperview()//for removing views
}
我开始学习 Swift 并决定构建一个没有故事板的应用程序。
我的 SceneDelegate scene
函数实例化一个 TabBarController
window = UIWindow(frame: UIScreen.main.bounds)
let tb = TabBarController()
window?.rootViewController = tb
window?.makeKeyAndVisible()
window?.windowScene = windowSceme
我有一个从 UITabBarController 扩展而来的 TabBarController,它几乎为选项卡栏设置了样式
对于 Tabbar 的每个项目,我都有一个 ViewController。出于这个问题的目的,我将指定第一个“Home”。
在扩展 ViewController 的主页中,我有以下内容
let homePageView = HomePageView()
override func viewWillLayoutSubviews() {
navigationController?.isNavigationBarHidden = true
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
homePageView.setupHomePage()
view.addSubview(homePageView)
}
override func viewWillDisappear(_ animated: Bool) {
homePageView.dispose()
}
控制器几乎只负责调用主要组件 HomePageView()
中将要显示在屏幕上的任何内容。最后,还有两个观点。一个旋转木马 HomePageCarrousel()
和一个 header HomePageSocialUp()
。此视图实例化后两个引用并以编程方式设置布局并将它们添加为子视图。它还包括一个将实例化的 类 设置为 nil 的处置函数,例如 --> Instantiate - homePageCarrousel = HomePageCarrousel()
并且处置函数具有 homePageCarrousel = nil
这很好用,但是当我通过标签栏导航离开当前视图控制器并导航回它时,现在我在 [=23] 中有两个 HomePageCarrousel()
和 HomePageSocialUp()
实例=]
我可能在某处持有一个强有力的参考,但我不知道什么时候。有人可以指出我应该在哪里调试它或者可能是什么导致了问题。
我还提供了复制的两个视图的代码,以防出现问题
HomePageSocialUp
class HomePageSocialUp: UIView {
let logo = UIImage(named: "LogoSmiles")
let socialImages: [UIImage] = [UIImage(named: "tripadvisor")!, UIImage(named: "instagram")!, UIImage(named: "facebook")!, UIImage(named: "linkedin")!]
func setupHeaderCircle() {
guard let insetTop = UIApplication.shared.keyWindow?.safeAreaInsets.top else {return}
let circlePath = UIBezierPath(arcCenter: CGPoint(x: UIScreen.main.bounds.width / 2, y: insetTop + 60), radius: CGFloat(90), startAngle: CGFloat(0), endAngle: CGFloat(Double.pi * 2), clockwise: true)
let shapeLayer = CAShapeLayer()
shapeLayer.path = circlePath.cgPath
shapeLayer.fillColor = UIColor.white.cgColor
layer.addSublayer(shapeLayer)
}
func setupSocialHeader() {
setupHeaderCircle()
layer.masksToBounds = true;
backgroundColor = UIColor.TintColor
layer.shadowColor = UIColor.lightGray.cgColor
layer.shadowOpacity = 0.8
layer.shadowOffset = CGSize(width: 0.0, height: 0.0)
layer.shadowRadius = 3.0
layer.masksToBounds = false
frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: 280)
let imageView = UIImageView()
guard let logo = logo else {return}
guard let insetTop = UIApplication.shared.keyWindow?.safeAreaInsets.top else {return}
imageView.frame = CGRect(x: CGFloat(Int((UIScreen.main.bounds.width - (logo.size.width)))) / 2, y: 120 - (logo.size.width / 2), width: logo.size.width, height: logo.size.height)
imageView.image = logo
addSubview(imageView)
}
}
HomePageCarrousel
class HomePageCarrousel: UIScrollView {
var images: [UIImage]?
var originX = 0
var numberOfIterations = 0
var timer: Timer?
func setupCarrousel() {
let x = (Int(UIScreen.main.bounds.width) - (Int(UIScreen.main.bounds.width) - 60)) / 2
frame = CGRect(x: x, y: (Int(frame.origin.y) - 350) / 2, width: Int(UIScreen.main.bounds.width) - 60, height: 350)
let newImage = textToImage(drawText: "Creating Smiles in unique places.", frame: frame, inImage: UIImage(named: "smiles1")!, atPoint: CGPoint(x: frame.origin.x + 20, y: frame.height - 20))
images = [newImage, UIImage(named: "smiles2")!]
guard timer == nil else { return }
timer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(startScrolling), userInfo: nil, repeats: true)
guard let imageCount = images?.count, let images = images else { return }
contentSize = CGSize(width: frame.width * CGFloat(images.count), height: frame.height)
for image in 0..<imageCount {
let imageView = UIImageView()
imageView.image = images[image]
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
let xPosition = frame.width * CGFloat(image)
imageView.frame = CGRect(x: xPosition, y: 0, width: frame.width, height: frame.height)
addSubview(imageView)
}
timer?.fire()
}
func textToImage(drawText text: String, frame: CGRect, inImage image: UIImage, atPoint point: CGPoint) -> UIImage {
let textColor = UIColor.white
let textFont = UIFont(name: "Helvetica Bold" , size: 12)!
let scale = UIScreen.main.scale
UIGraphicsBeginImageContextWithOptions(image.size, false, scale)
let textFontAttributes = [
NSAttributedString.Key.font: textFont,
NSAttributedString.Key.foregroundColor: textColor,
] as [NSAttributedString.Key : Any]
image.draw(in: CGRect(origin: CGPoint.zero, size: image.size))
text.draw(in: frame, withAttributes: textFontAttributes)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage!
}
@objc func startScrolling() {
print(originX)
guard let images = images else { return }
if originX == images.count {
originX = 0
numberOfIterations += 1
}
if numberOfIterations > 2 {
timer?.invalidate()
timer = nil
numberOfIterations = 0
}
let x = CGFloat(originX) * frame.size.width
setContentOffset(CGPoint(x: x, y: 0), animated: true)
originX += 1
}
}
在此先致谢
您是否尝试删除子视图,例如
homePageView.subviews.forEach { (view) in
//taking appropriate action to whichever view you want
view.removeFromSuperview()//for removing views
}