2017-09-10 258 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将删除引用您要删除的视图的任何约束,或引用要删除的视图的子树中的任何视图的任何约束。这意味着自动布局系统将重新排列视图。

相关问题