2017-09-10 267 views
0

我有兩個視圖,其中一個是mainVideoView(灰色),另一個是subVideoView(紅色)。它們都是UIApplication.shared.keyWindow的子視圖。當一個窗口的子視圖被刪除時,視圖大小會自動設置爲窗口大小

當我嘗試,並儘量減少他們(使用func minimiseOrMaximiseViews,它們會最小化(如下面的圖所示)。

之後,我想從窗口中刪除subVideoView。我嘗試刪除的那一刻subVideoView(使用func removeSubVideoViewFromVideoView()調用func minimiseOrMaximiseViews),mainVideoView放大到全屏尺寸,我不確定爲什麼會發生這種情況,我希望它保持在相同的尺寸下。可以做到這一點嗎?

enter image description here

這是我如何設置的意見

func configureVideoView(){ 
    videoView.backgroundColor = UIColor.darkGray 
    videoView.tag    = 0 // To identify view during animation 

    // ADDING TAP GESTURE TO MAXIMISE THE VIEW WHEN ITS SMALL 
    let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(handleTap(gestureRecognizer:))) 
    videoView.addGestureRecognizer(tapGestureRecognizer) 

    // ADDING PAN GESTURE RECOGNISER TO MAKE VIDEOVIEW MOVABLE INSIDE PARENT VIEW 
    videoView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.dragView))) 


    guard let window = UIApplication.shared.keyWindow else{ 
    return 
    } 

    window.addSubview(videoView) 

    videoView.translatesAutoresizingMaskIntoConstraints = false 

    let viewsDict = ["videoView" : videoView] as [String : Any] 

    // SETTING CONSTRAINTS 
    window.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[videoView]|", options: [], metrics: nil, views: viewsDict)) 
    window.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[videoView]|", options: [], metrics: nil, views: viewsDict)) 


    window.layoutIfNeeded() // Lays out subviews immediately 
    window.bringSubview(toFront: videoView) // To bring subView to front 

    print("Videoview constraints in configureVideoView \(videoView.constraints)") 

} 

func configureSubVideoView(){ 

    subVideoView.backgroundColor = UIColor.red 
    subVideoView.tag    = 1 // To identify view during animation 
    subVideoView.isHidden   = true 


    // Adding Pan Gesture recogniser to make subVideoView movable inside parentview 
    subVideoView.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(self.dragView))) 

    // Constraining subVideoView to window to ensure that minimising and maximising animation works properly 
    constrainSubVideoViewToWindow() 

} 

func constrainSubVideoViewToWindow(){ 

    //self.subVideoView.setNeedsLayout() 
    guard let window = UIApplication.shared.keyWindow else{ 
     print("Window does not exist") 
     return 
    } 

    guard !window.subviews.contains(subVideoView)else{ // Does not allow to go through the below code if the window already contains subVideoView 
     return 
    } 

    if self.videoView.subviews.contains(subVideoView){ // If videoView contains subVideoView remove subVideoView 

     subVideoView.removeFromSuperview() 

    } 

    window.addSubview(subVideoView) 
     // Default constraints to ensure that the subVideoView is initialised with maxSubVideoViewWidth & maxSubVideoViewHeight and is positioned above buttons 

    let bottomOffset = buttonDiameter + buttonStackViewBottomPadding + padding 

    subVideoView.translatesAutoresizingMaskIntoConstraints = false 

    let widthConstraint = NSLayoutConstraint(item: subVideoView, attribute: .width, relatedBy: .equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1.0, constant: maxSubVideoViewWidth) 

    let heightConstraint = NSLayoutConstraint(item: subVideoView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: NSLayoutAttribute.notAnAttribute, multiplier: 1.0, constant: maxSubVideoViewHeight) 

    let rightConstraint = NSLayoutConstraint(item: subVideoView, attribute: .trailing, relatedBy: .equal, toItem: window, attribute: .trailing, multiplier: 1.0, constant: -padding) 

    let bottomConstraint = NSLayoutConstraint(item: subVideoView, attribute: .bottom, relatedBy: .equal, toItem: window, attribute: .bottom, multiplier: 1.0, constant: -bottomOffset) 

    var constraintsArray = [NSLayoutConstraint]() 
    constraintsArray.append(widthConstraint) 
    constraintsArray.append(heightConstraint) 
    constraintsArray.append(rightConstraint) 
    constraintsArray.append(bottomConstraint) 

    window.addConstraints(constraintsArray) 

    window.layoutIfNeeded() // Lays out subviews immediately 
    subVideoView.setViewCornerRadius() 
    window.bringSubview(toFront: subVideoView) // To bring subView to front 

} 

這是我如何動畫的意見和消除subVideoView

func minimiseOrMaximiseViews(animationType: String){ 

    let window = UIApplication.shared.keyWindow 

    let buttonStackViewHeight = buttonsStackView.frame.height 

    if animationType == "maximiseView" { 
     constrainSubVideoViewToWindow() 

    } 


    UIView.animate(withDuration: 0.3, delay: 0, options: [], 

     animations: { [unowned self] in // "[unowned self] in" added to avoid strong reference cycles, 
      switch animationType { 

      case "minimiseView" : 

       self.hideControls() 

       // Minimising self i.e videoView 
       self.videoView.frame = CGRect(x:  self.mainScreenWidth - self.videoViewWidth - self.padding, 
               y:  self.mainScreenHeight - self.videoViewHeight - self.padding, 
               width: self.videoViewWidth, 
               height: self.videoViewHeight) 


       // Minimising subVideoView 
       self.subVideoView.frame = CGRect(x:  self.mainScreenWidth - self.minSubVideoViewWidth - self.padding * 2, 
                y:  self.mainScreenHeight - self.minSubVideoViewHeight - self.padding * 2, 
                width: self.minSubVideoViewWidth, 
                height: self.minSubVideoViewHeight) 
       window?.layoutIfNeeded() 


       self.videoView.setViewCornerRadius() 
       self.subVideoView.setViewCornerRadius() 

       print("self.subVideoView.frame AFTER setting: \(self.subVideoView.frame)") 



      default: 
       break 
      } 
    }) { [unowned self] (finished: Bool) in // This will be called when the animation completes, and its finished value will be true 

     if animationType == "minimiseView" { 

      // **** Removing subVideoView from videoView **** 
      self.removeSubVideoViewFromVideoView() 

     } 
    } 


} 

func removeSubVideoViewFromVideoView(){ 

    //self.subVideoView.setNeedsLayout() 

    guard let window = UIApplication.shared.keyWindow else{ 
     return 
    } 

    guard !self.videoView.subviews.contains(subVideoView)else{ // Does not allow to go through the below code if the videoView already contains subVideoView 
     return 
    } 

    if window.subviews.contains(subVideoView) {  // removing subVideoView from window 
     subVideoView.removeFromSuperview() // *** CAUSE OF ISSUE *** 

    } 

    guard !window.subviews.contains(subVideoView) else{ 
     return 
    } 

    videoView.addSubview(subVideoView) 
} 

回答

2

的videoView和subVideoView是通過自動佈局佈局。在自動佈局中,如果您想更改框架,則必須更新約束。

調用removeFromSuperView將刪除引用您要刪除的視圖的任何約束,或引用要刪除的視圖的子樹中的任何視圖的任何約束。這意味着自動佈局系統將重新排列視圖。

相關問題