iOS Revisited: Safe Area Layout Guides

Hot

Post Top Ad

Showing posts with label Safe Area Layout Guides. Show all posts
Showing posts with label Safe Area Layout Guides. Show all posts

25 Oct 2017

Adaptive Autolayout Programmatically For iPhone X Using SafeAreaLayoutGuide - Swift 4

10/25/2017 10:46:00 am 0
Adaptive Autolayout mainly used to choose various layouts in different devices with orientations. Here in this article we create two layouts, one is for Portrait orientation and second on is for Landscape orientation. Here we are doing mainly for iPhone 10, so we have to use SafeAreaLayoutGuide.

Adaptive Autolayout Programmatically For iPhone X Using SafeAreaLayoutGuide - Swift 4


Create Project:

Firstly create new Xcode project.

Open ViewController.swift file and add the following properties:

let imgView : UIImageView = {
    let imageView = UIImageView()
    imageView.translatesAutoresizingMaskIntoConstraints = false
    imageView.image = UIImage(named: "kitten.jpg")
    imageView.contentMode = .scaleAspectFill
    imageView.clipsToBounds = true
    return imageView
}()

let sampleLabel : UILabel = {
    let label = UILabel()
    label.translatesAutoresizingMaskIntoConstraints = false
    label.numberOfLines = 0
    label.font = UIFont.systemFont(ofSize: 30.0)
    label.textAlignment = .center
    label.adjustsFontSizeToFitWidth = true
    label.text = "The Ragdoll is a cat breed with blue eyes and a distinct colourpoint coat. It is a large and muscular semi-longhair cat with a soft and silky coat. Like all long haired cats, Ragdolls need grooming to ensure their fur does not mat."
    label.textColor = UIColor.darkGray
    return label
}()

Here we are use kitten.jpg, replace that with your image.

ImageView Constraints:

The imageview should look like above image. So first add imageView to View then create constraints for imageView relatively to view.

Add the following method:

func addUIElements() {
    let guide = view.safeAreaLayoutGuide
    
    // imgView Layouts
    view.addSubview(imgView)
    let defaultImgTop = imgView.topAnchor.constraint(equalTo: guide.topAnchor, constant: 0.0)
    let defaultImgLeading = imgView.leadingAnchor.constraint(equalTo: guide.leadingAnchor, constant: 0.0)
    
    // portrait
    let portraitImgTrailing = imgView.trailingAnchor.constraint(equalTo: guide.trailingAnchor, constant: 0.0)
    let portraitImgHeight = imgView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.5)

    // .....
}
Here we are using view's safeAreaLayoutGuide as base layout guide.

Label Constraints:

Label also should look like above image. So first add label to View then create constraints for label relatively to view.

Then add the following code to the end of addUIElements() method:

// sampleLabel Layouts
view.addSubview(sampleLabel)
let defaultLblTrailing = sampleLabel.trailingAnchor.constraint(equalTo: guide.trailingAnchor, constant: -10.0)
let defaultLblBottom = sampleLabel.bottomAnchor.constraint(equalTo: guide.bottomAnchor, constant: 0.0)

// portrait
let portraitLblBottom = sampleLabel.topAnchor.constraint(equalTo: imgView.bottomAnchor, constant: 0.0)
let portraitLblLeading = sampleLabel.leadingAnchor.constraint(equalTo: guide.leadingAnchor, constant: 10.0)

So we successfully created layouts for imageview and label.

Next step is adding constraints to view. To do add the following line next to the constraints.

let defaultConstraints = [defaultImgTop, defaultImgLeading, defaultLblBottom, defaultLblTrailing, portraitImgHeight, portraitImgTrailing, portraitLblBottom, portraitLblLeading]
view.addConstraints(defaultConstraints)

Then finally call the addUIElements() method in viewDidLoad() and Run the project, we will output as follow:

Adaptive Autolayout Programmatically For iPhone X Portrait

That's Great! What about landscape?

Let's check, that's was bad layout in landscape.

Landscape Constraints:

So for Landscape create new layouts.

Add following code just before defaultConstraints creation:

// ImageView Landscape Constraints
let landscapeImgBottom = imgView.bottomAnchor.constraint(equalTo: guide.bottomAnchor, constant: 0.0)
let landscapeImgWidth = imgView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.5)

// Label Landscape Constraints
let landscapeLblTop = sampleLabel.topAnchor.constraint(equalTo: guide.topAnchor, constant: 0.0)
let landscapeLblTrailing = sampleLabel.leadingAnchor.constraint(equalTo: imgView.trailingAnchor, constant: 10.0)

Next create two NSLayoutConstraint arrays, for that add the following properties:

var portraitConstraints: [NSLayoutConstraint] = []
var landscapeConstraints: [NSLayoutConstraint] = []

portraitConstraints is to store all constraints required for portrait orientation.
landscapeConstraints is to store all constraints required for landscape orientation.

Then replace defaultConstraints with the following code:

let defaultConstraints = [defaultImgTop, defaultImgLeading, defaultLblBottom, defaultLblTrailing]
portraitConstraints = [portraitImgHeight, portraitImgTrailing, portraitLblBottom, portraitLblLeading]
landscapeConstraints = [landscapeImgWidth, landscapeImgBottom, landscapeLblTop, landscapeLblTrailing]

Next add the observer to listen to orientation changes, add the following code in viewDidLoad() method:

NotificationCenter.default.addObserver(self, selector: #selector(self.toggleConstraints), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)

Next add the method for toggle the constraints, add the following method:

@objc func toggleConstraints() {
    if UIDevice.current.orientation.isLandscape {
        view.removeConstraints(portraitConstraints)
        view.addConstraints(landscapeConstraints)
    }else {
        view.removeConstraints(landscapeConstraints)
        view.addConstraints(portraitConstraints)
    }
}

Next call the above method at the end of addUIElements() methods.

Now Build and Run, change the orientation we will see the following screen in landscape orientation.

Adaptive Autolayout Programmatically For iPhone X Landscape

Download sample project with examples :

Read More

7 Oct 2017

Safe Area Layout Guides Tutorial iOS 11

10/07/2017 03:39:00 am 0
The layout guide representing the portion of your view that is unobscured by bars and other content. In iOS 11, Apple is deprecating the top and bottom layout guides and replacing them with a single safe area layout guide.

Safe Area Layout Guides Tutorial iOS 11

  • Bottom layout guide & top layout guide are deprecated from iOS 11.
  • We can change safeArea layout insets by using a safeAreaInsets property.
  • safeAreaInsetsDidChange() method will call when the safe area of the view changes.
In iPhone X we have to use safe area layout otherwise in landscape mode the top notch will cut some content as below:

iPone X top notch will cut some content in landscape

Safe area layout guide Using Storyboards:

It's easy by using storyboard, just go to storyboard and select any one of controller.

Left side go to File inspector there simple check mark the use Safe Area Layout Guides.

File inspector there simple check mark the use Safe Area Layout Guides.

We can migrate old projects to Safe area layout guide.

The Storyboard automatically replaces the top and bottom layout guides with a safe area and updates the constraints:

Safe area layout guide Programmatically:

Create your constraints in code use the safeAreaLayoutGuide property of UIView to get the relevant layout anchors.

Now unless you are targeting iOS 11 only you will need to wrap the safe area layout guide constraints with #available and fall back to top and bottom layout guides for earlier iOS versions:

Code:

if #available(iOS 11, *) {
    let guide = view.safeAreaLayoutGuide
    label.topAnchor.constraint(equalTo: guide.topAnchor).isActive = true
    label.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    label.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
   
} else {
    label.topAnchor.constraint(equalTo: topLayoutGuide.topAnchor).isActive = true
    label.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    label.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
}

Conclusion:

  • The safeAreaLayoutGuide is a property of UIView where topLayoutGuide and bottomLayoutGuide are properties of UIViewController
  • The constraintEqualToSystemSpacingBelow method is new in iOS 11 and removes the need to hard code standard spacing. There are also less than and greater than versions. For horizontal spacing there is also constraintEqualToSystemSpacingAfter.
  • We can increase or decrease of safe area size using safeAreaInsets property.

Next Steps :

iOS 11[Swift 4] Navigation Bar With Large Titles and LargeTitleTextAttributes

Read More

Post Top Ad