4
votes

I am loading a nib file of a custom UIView Subclass into my viewcontroller. the problem here is , when i change orientation to landscape, the view still shows in portrait frames. I want it's frame to be set in landscape mode also.

below is my code:-

class CustomPopUpView: UIView {

@IBOutlet weak var vWtitle: UIView!
@IBOutlet weak var lblTitle: UILabel!
@IBOutlet weak var lblContent: UILabel!
@IBOutlet weak var vwAlertSub: UIView!
@IBOutlet weak var btnCenter: UIButton!

var view: UIView!

func xibSetup() {
    view = loadViewFromNib()
    view.frame = bounds
    view.autoresizingMask = [UIViewAutoresizing.flexibleWidth, UIViewAutoresizing.flexibleHeight]
    addSubview(view)
    lblTitle.adjustsFontSizeToFitWidth = true
    view.backgroundColor = UIColor.black.withAlphaComponent(0.6)
    self.showAnimate()
}

func loadViewFromNib() -> UIView {
    let bundle = Bundle(for: type(of: self))
    let nib = UINib(nibName: "CustomPopUpView", bundle: bundle)
    let view = nib.instantiate(withOwner: self, options: nil)[0] as! UIView
    return view
}

override func layoutSubviews(){
    super.layoutSubviews()
    print("LayoutSubViews...............")
   // view.frame = bounds
}

func showAnimate()
{
    self.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)
    self.alpha = 0.0;
    UIView.animate(withDuration: 0.25, animations: {
        self.alpha = 1.0
        self.transform = CGAffineTransform(scaleX: 1.0, y: 1.0)
    });
}

func removeAnimate()
{
    UIView.animate(withDuration: 0.25, animations: {
        self.transform = CGAffineTransform(scaleX: 1.3, y: 1.3)
        self.alpha = 0.0;
    }, completion:{(finished : Bool)  in
        if (finished)
        {
            self.removeFromSuperview()
        }
    });
}


init(frame: CGRect, titleTxt:String, contentText: String, leftButtonText:String, rightButtonText:String) {
    super.init(frame: frame)

    xibSetup()
    lblTitle.text = titleTxt
    lblContent.text = contentText

    if leftButtonText.characters.count > 0 {
        btnLeft.isHidden = false
        btnLeft.setTitle(leftButtonText,for: .normal)
    }
    else {
        btnLeft.isHidden = true
    }
    if rightButtonText.characters.count > 0 {
        btnRight.isHidden = false
        btnRight.setTitle(rightButtonText,for: .normal)
    }
    else {
        btnRight.isHidden = true
    }
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}



@IBAction func btnCenterTapped(_ sender: Any) {
    self.removeAnimate()
}

Do I need to set the frame once again in layoutsubviews method? Or is there any other method for UIView orientation change? (just like we have for viewcontroller's orientation method "viewWillLayoutSubviews")

3
how you are adding CustomPopUpView to view controller? show those code.Surya Subenthiran
I dont want to write any code about this view resizing in viewcontrollermirza

3 Answers

1
votes

I think set the frame once again not correct since auto-layouts came out. in swift override func layoutSubviews() { super.layoutSubviews() self.setNeedsDisplay() } since layoutSubviews() is a View Method .

or you can observe in viewDidLoad NSNotificationCenter.defaultCenter().addObserver(self, selector: "functionThatYouWantTriggeredOnRotation", name: UIDeviceOrientationDidChangeNotification, object: nil)

Alternatively you can just provide the override for viewWillTransition and not have to add an observer for the UIDeviceOrientationDidChangeNotification.

override func viewWillTransitionToSize(size: CGSize,
  withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)
{
    if UIDevice.currentDevice().orientation.isLandscape {
            //do your thing
        }
}
0
votes

This method will help you for grabbing orientation change.So if you want to update something during landscape as for your nib height or something, change your code by using this method.

override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
        if UIDevice.currentDevice().orientation.isLandscape.boolValue {
            print("Landscape")
            //Change your code here for landscape
        } else {
            print("Portrait")
            //Change your code here for portrait
        }
    }

Swift 3 version:

override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        super.viewWillTransition(to: size, with: coordinator)

    }
0
votes

Swift 4.2 version:

This is the one way to deal with this problem, inside your UIView subclass.

First you need to set observer in your UIView subclass.

 override init(frame: CGRect) {
        super.init(frame:frame)
        NotificationCenter.default.addObserver(self, selector: #selector(updateLayout), name: UIDevice.orientationDidChangeNotification, object: nil)
     //UI setup
    }

Than in your targer function you can set new frame for your custom view.

@objc func updateLayout(){
        if UIDevice.current.orientation.isLandscape {
            self.frame = CGRect(.....)
        } else {
            self.frame = CGRect(......)
        }
    }

Dontr forget to remove your obsserver in deinit method of your UIView.

 deinit {
        NotificationCenter.default.removeObserver(self,
                                                  name: UIDevice.orientationDidChangeNotification,
                                                  object: nil)
}