导航离开时如何从一个 ViewController 上的 UIView 子视图中处理

Posted

技术标签:

【中文标题】导航离开时如何从一个 ViewController 上的 UIView 子视图中处理【英文标题】:How to dispose from UIView subviews on one ViewController when navigating away from it 【发布时间】:2020-11-03 19:22:54 【问题描述】:

我开始学习 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。出于这个问题的目的,我将指定第一个“家”。

在扩展 ViewController 的 Home 中,我有以下内容

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()

Controller 几乎只负责调用主要组件HomePageView() 中将在屏幕上显示的任何内容。最后,还有两个观点。一个转盘HomePageCarrousel() 和一个标题HomePageSocialUp()。该视图实例化了后者所引用的两个,并以编程方式设置布局并将它们添加为子视图。它还包括一个将实例化的类设置为 nil 的 dispose 函数,例如 --> Instantiate - homePageCarrousel = HomePageCarrousel() 和 dispose 函数有 homePageCarrousel = nil

这工作得很好,但是当我通过标签栏离开当前视图控制器并导航回它时,现在我在 HomeView 中有两个 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
   

先谢谢

【问题讨论】:

【参考方案1】:

您是否尝试过删除子视图,例如

    homePageView.subviews.forEach  (view) in
    //taking appropriate action to whichever view you want
        view.removeFromSuperview()//for removing views
    

【讨论】:

这是绝对正确的,但为了以更快速的方式获取代码,我使用了 subviews.forEach$0.removeFromSuperview()

以上是关于导航离开时如何从一个 ViewController 上的 UIView 子视图中处理的主要内容,如果未能解决你的问题,请参考以下文章

离开时如何杀死Android活动,使其无法从后退按钮访问?

如何从 ViewController 中分离(推送)到 NavigationController 中嵌入的另一个 ViewController?

如果我使用 TabBar Navigation,如何从 AppDelegate 调用 viewcontroller 方法

如何从 iOS 中的 NSObject 类导航到 ViewController?

目标 C:如何从当前 ViewController 后面的 ViewController 获取导航控制器

如何从 UIView 类的 xib 文件导航到 ViewController