├── .DS_Store ├── Images ├── .DS_Store ├── image1.png ├── image10.png ├── image11.png ├── image12.png ├── image13.png ├── image2.png ├── image3.png ├── image4.png ├── image5.png ├── image6.png ├── image7.png ├── image8.png └── image9.png └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imanoupetit/Margins-And-Safe-Area/75da78e1f0f35ca0bc7a2dd955da23993f2caca3/.DS_Store -------------------------------------------------------------------------------- /Images/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imanoupetit/Margins-And-Safe-Area/75da78e1f0f35ca0bc7a2dd955da23993f2caca3/Images/.DS_Store -------------------------------------------------------------------------------- /Images/image1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imanoupetit/Margins-And-Safe-Area/75da78e1f0f35ca0bc7a2dd955da23993f2caca3/Images/image1.png -------------------------------------------------------------------------------- /Images/image10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imanoupetit/Margins-And-Safe-Area/75da78e1f0f35ca0bc7a2dd955da23993f2caca3/Images/image10.png -------------------------------------------------------------------------------- /Images/image11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imanoupetit/Margins-And-Safe-Area/75da78e1f0f35ca0bc7a2dd955da23993f2caca3/Images/image11.png -------------------------------------------------------------------------------- /Images/image12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imanoupetit/Margins-And-Safe-Area/75da78e1f0f35ca0bc7a2dd955da23993f2caca3/Images/image12.png -------------------------------------------------------------------------------- /Images/image13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imanoupetit/Margins-And-Safe-Area/75da78e1f0f35ca0bc7a2dd955da23993f2caca3/Images/image13.png -------------------------------------------------------------------------------- /Images/image2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imanoupetit/Margins-And-Safe-Area/75da78e1f0f35ca0bc7a2dd955da23993f2caca3/Images/image2.png -------------------------------------------------------------------------------- /Images/image3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imanoupetit/Margins-And-Safe-Area/75da78e1f0f35ca0bc7a2dd955da23993f2caca3/Images/image3.png -------------------------------------------------------------------------------- /Images/image4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imanoupetit/Margins-And-Safe-Area/75da78e1f0f35ca0bc7a2dd955da23993f2caca3/Images/image4.png -------------------------------------------------------------------------------- /Images/image5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imanoupetit/Margins-And-Safe-Area/75da78e1f0f35ca0bc7a2dd955da23993f2caca3/Images/image5.png -------------------------------------------------------------------------------- /Images/image6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imanoupetit/Margins-And-Safe-Area/75da78e1f0f35ca0bc7a2dd955da23993f2caca3/Images/image6.png -------------------------------------------------------------------------------- /Images/image7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imanoupetit/Margins-And-Safe-Area/75da78e1f0f35ca0bc7a2dd955da23993f2caca3/Images/image7.png -------------------------------------------------------------------------------- /Images/image8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imanoupetit/Margins-And-Safe-Area/75da78e1f0f35ca0bc7a2dd955da23993f2caca3/Images/image8.png -------------------------------------------------------------------------------- /Images/image9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/imanoupetit/Margins-And-Safe-Area/75da78e1f0f35ca0bc7a2dd955da23993f2caca3/Images/image9.png -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Margins And Safe Area 2 | 3 | 13 examples with big coloured squares to understand margins and safe area in UIKit (iOS 11) 4 | 5 | 1. [`UIView`'s `safeAreaLayoutGuide` + `UIView`'s `layoutMarginsGuide`](#1) 6 | 1. [`UIView`'s `layoutMargins`](#2) 7 | 1. [`UIView`'s `directionalLayoutMargins`](#3) 8 | 1. [`UIView`'s `directionalLayoutMargins` + `autoresizingMask`](#4) 9 | 1. [`UIViewController`'s `additionalSafeAreaInsets`](#5) 10 | 1. [`UIView`'s `insetsLayoutMarginsFromSafeArea`](#6) 11 | 1. [`UIViewController`'s `viewRespectsSystemMinimumLayoutMargins`](#7) 12 | 1. [`UIView`'s `preservesSuperviewLayoutMargins`](#8) 13 | 1. [`NSLayoutYAxisAnchor`'s `constraintEqualToSystemSpacingBelow(_:multiplier:)` + `NSLayoutYAxisAnchor`'s `constraintEqualToSystemSpacingAfter(_:multiplier:)`](#9) 14 | 1. [`UIStackView`'s `isLayoutMarginsRelativeArrangement`](#10) 15 | 1. [`UIScrollView`'s `contentInsetAdjustmentBehavior` + `UIScrollView`'s `contentInset` + `UIScrollView`'s `contentLayoutGuide`](#11) 16 | 1. [`UICollectionView`'s `contentInsetAdjustmentBehavior`](#12) 17 | 1. [`UITableView`'s `insetsContentViewsToSafeArea`](#13) 18 | 19 | --- 20 | 21 | ### 1. `UIView`'s `safeAreaLayoutGuide` + `UIView`'s `layoutMarginsGuide` 22 | ```swift 23 | override func viewDidLoad() { 24 | let yellowView = UIView() 25 | yellowView.backgroundColor = .yellow 26 | view.addSubview(yellowView) 27 | yellowView.translatesAutoresizingMaskIntoConstraints = false 28 | view.safeAreaLayoutGuide.topAnchor.constraint(equalTo: yellowView.topAnchor).isActive = true 29 | view.safeAreaLayoutGuide.leadingAnchor.constraint(equalTo: yellowView.leadingAnchor).isActive = true 30 | view.safeAreaLayoutGuide.trailingAnchor.constraint(equalTo: yellowView.trailingAnchor).isActive = true 31 | view.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: yellowView.bottomAnchor).isActive = true 32 | 33 | let cyanView = UIView() 34 | cyanView.backgroundColor = .cyan 35 | yellowView.addSubview(cyanView) 36 | cyanView.translatesAutoresizingMaskIntoConstraints = false 37 | yellowView.layoutMarginsGuide.topAnchor.constraint(equalTo: cyanView.topAnchor).isActive = true 38 | yellowView.layoutMarginsGuide.leadingAnchor.constraint(equalTo: cyanView.leadingAnchor).isActive = true 39 | yellowView.layoutMarginsGuide.trailingAnchor.constraint(equalTo: cyanView.trailingAnchor).isActive = true 40 | yellowView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: cyanView.bottomAnchor).isActive = true 41 | } 42 | ``` 43 | 44 | 45 | 46 | --- 47 | 48 | ### 2. `UIView`'s `layoutMargins` 49 | ```swift 50 | override func viewDidLoad() { 51 | let brownView = UIView() 52 | brownView.layoutMargins = UIEdgeInsets(top: 40, left: 40, bottom: 40, right: 40) 53 | brownView.backgroundColor = .brown 54 | view.addSubview(brownView) 55 | brownView.translatesAutoresizingMaskIntoConstraints = false 56 | brownView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true 57 | brownView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true 58 | brownView.widthAnchor.constraint(equalToConstant: 200).isActive = true 59 | brownView.heightAnchor.constraint(equalToConstant: 200).isActive = true 60 | 61 | let blueView = UIView() 62 | blueView.backgroundColor = .blue 63 | brownView.addSubview(blueView) 64 | blueView.translatesAutoresizingMaskIntoConstraints = false 65 | brownView.layoutMarginsGuide.topAnchor.constraint(equalTo: blueView.topAnchor).isActive = true 66 | brownView.layoutMarginsGuide.leadingAnchor.constraint(equalTo: blueView.leadingAnchor).isActive = true 67 | brownView.layoutMarginsGuide.trailingAnchor.constraint(equalTo: blueView.trailingAnchor).isActive = true 68 | brownView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: blueView.bottomAnchor).isActive = true 69 | } 70 | ``` 71 | 72 | 73 | 74 | --- 75 | 76 | ### 3. `UIView`'s `directionalLayoutMargins` 77 | ```swift 78 | override func viewDidLoad() { 79 | let redView = UIView() 80 | redView.backgroundColor = .red 81 | redView.directionalLayoutMargins = NSDirectionalEdgeInsets(top: 70, leading: 70, bottom: 70, trailing: 70) 82 | view.addSubview(redView) 83 | redView.translatesAutoresizingMaskIntoConstraints = false 84 | view.safeAreaLayoutGuide.topAnchor.constraint(equalTo: redView.topAnchor).isActive = true 85 | view.safeAreaLayoutGuide.leadingAnchor.constraint(equalTo: redView.leadingAnchor).isActive = true 86 | view.safeAreaLayoutGuide.trailingAnchor.constraint(equalTo: redView.trailingAnchor).isActive = true 87 | view.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: redView.bottomAnchor).isActive = true 88 | 89 | let greenView = UIView() 90 | greenView.backgroundColor = .green 91 | redView.addSubview(greenView) 92 | greenView.translatesAutoresizingMaskIntoConstraints = false 93 | redView.layoutMarginsGuide.topAnchor.constraint(equalTo: greenView.topAnchor).isActive = true 94 | redView.layoutMarginsGuide.leadingAnchor.constraint(equalTo: greenView.leadingAnchor).isActive = true 95 | redView.layoutMarginsGuide.trailingAnchor.constraint(equalTo: greenView.trailingAnchor).isActive = true 96 | redView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: greenView.bottomAnchor).isActive = true 97 | } 98 | ``` 99 | 100 | 101 | 102 | --- 103 | 104 | ### 4. `UIView`'s `directionalLayoutMargins` + `autoresizingMask` 105 | ```swift 106 | override func viewDidLoad() { 107 | view.directionalLayoutMargins = NSDirectionalEdgeInsets(top: 100, leading: 100, bottom: 100, trailing: 100) 108 | 109 | let orangeView = UIView() 110 | orangeView.backgroundColor = .orange 111 | view.addSubview(orangeView) 112 | orangeView.frame = CGRect( 113 | x: view.directionalLayoutMargins.leading, 114 | y: view.directionalLayoutMargins.top, 115 | width: view.frame.width - view.directionalLayoutMargins.leading - view.directionalLayoutMargins.trailing, 116 | height: view.frame.height - view.directionalLayoutMargins.top - view.directionalLayoutMargins.bottom 117 | ) 118 | orangeView.autoresizingMask = [.flexibleWidth, .flexibleHeight] 119 | } 120 | ``` 121 | 122 | 123 | 124 | --- 125 | 126 | ### 5. `UIViewController`'s `additionalSafeAreaInsets` 127 | ```swift 128 | override func viewDidLoad() { 129 | additionalSafeAreaInsets = UIEdgeInsets(top: 100, left: 100, bottom: 100, right: 100) 130 | 131 | let brownView = UIView() 132 | brownView.backgroundColor = .brown 133 | view.addSubview(brownView) 134 | brownView.translatesAutoresizingMaskIntoConstraints = false 135 | view.safeAreaLayoutGuide.topAnchor.constraint(equalTo: brownView.topAnchor).isActive = true 136 | view.safeAreaLayoutGuide.leadingAnchor.constraint(equalTo: brownView.leadingAnchor).isActive = true 137 | view.safeAreaLayoutGuide.trailingAnchor.constraint(equalTo: brownView.trailingAnchor).isActive = true 138 | view.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: brownView.bottomAnchor).isActive = true 139 | } 140 | ``` 141 | 142 | 143 | 144 | --- 145 | 146 | ### 6. `UIView`'s `insetsLayoutMarginsFromSafeArea` 147 | ```swift 148 | override func viewDidLoad() { 149 | view.directionalLayoutMargins = NSDirectionalEdgeInsets(top: 5, leading: 5, bottom: 5, trailing: 5) 150 | view.insetsLayoutMarginsFromSafeArea = false 151 | 152 | let magentaView = UIView() 153 | magentaView.backgroundColor = .magenta 154 | view.addSubview(magentaView) 155 | magentaView.translatesAutoresizingMaskIntoConstraints = false 156 | view.layoutMarginsGuide.topAnchor.constraint(equalTo: magentaView.topAnchor).isActive = true 157 | view.layoutMarginsGuide.leadingAnchor.constraint(equalTo: magentaView.leadingAnchor).isActive = true 158 | view.layoutMarginsGuide.trailingAnchor.constraint(equalTo: magentaView.trailingAnchor).isActive = true 159 | view.layoutMarginsGuide.bottomAnchor.constraint(equalTo: magentaView.bottomAnchor).isActive = true 160 | } 161 | ``` 162 | 163 | 164 | 165 | --- 166 | 167 | ### 7. `UIViewController`'s `viewRespectsSystemMinimumLayoutMargins` 168 | ```swift 169 | override func viewDidLoad() { 170 | viewRespectsSystemMinimumLayoutMargins = false 171 | view.insetsLayoutMarginsFromSafeArea = false 172 | view.layoutMargins = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5) 173 | 174 | let greenView = UIView() 175 | greenView.backgroundColor = .green 176 | view.addSubview(greenView) 177 | greenView.translatesAutoresizingMaskIntoConstraints = false 178 | view.layoutMarginsGuide.topAnchor.constraint(equalTo: greenView.topAnchor).isActive = true 179 | view.layoutMarginsGuide.leadingAnchor.constraint(equalTo: greenView.leadingAnchor).isActive = true 180 | view.layoutMarginsGuide.trailingAnchor.constraint(equalTo: greenView.trailingAnchor).isActive = true 181 | view.layoutMarginsGuide.bottomAnchor.constraint(equalTo: greenView.bottomAnchor).isActive = true 182 | } 183 | ```` 184 | 185 | 186 | 187 | --- 188 | 189 | ### 8. `UIView`'s `preservesSuperviewLayoutMargins` 190 | ```swift 191 | override func viewDidLoad() { 192 | viewRespectsSystemMinimumLayoutMargins = false 193 | view.insetsLayoutMarginsFromSafeArea = false 194 | view.layoutMargins = UIEdgeInsets(top: 140, left: 140, bottom: 140, right: 140) 195 | 196 | let orangeView = UIView() 197 | orangeView.preservesSuperviewLayoutMargins = true 198 | orangeView.backgroundColor = .orange 199 | view.addSubview(orangeView) 200 | orangeView.translatesAutoresizingMaskIntoConstraints = false 201 | view.topAnchor.constraint(equalTo: orangeView.topAnchor).isActive = true 202 | view.leadingAnchor.constraint(equalTo: orangeView.leadingAnchor).isActive = true 203 | view.trailingAnchor.constraint(equalTo: orangeView.trailingAnchor).isActive = true 204 | view.bottomAnchor.constraint(equalTo: orangeView.bottomAnchor).isActive = true 205 | 206 | let yellowView = UIView() 207 | yellowView.backgroundColor = .yellow 208 | orangeView.addSubview(yellowView) 209 | yellowView.translatesAutoresizingMaskIntoConstraints = false 210 | orangeView.layoutMarginsGuide.topAnchor.constraint(equalTo: yellowView.topAnchor).isActive = true 211 | orangeView.layoutMarginsGuide.leadingAnchor.constraint(equalTo: yellowView.leadingAnchor).isActive = true 212 | orangeView.layoutMarginsGuide.trailingAnchor.constraint(equalTo: yellowView.trailingAnchor).isActive = true 213 | orangeView.layoutMarginsGuide.bottomAnchor.constraint(equalTo: yellowView.bottomAnchor).isActive = true 214 | } 215 | ``` 216 | 217 | 218 | 219 | --- 220 | 221 | ### 9. `NSLayoutYAxisAnchor`'s `constraintEqualToSystemSpacingBelow(_:multiplier:)` + `NSLayoutYAxisAnchor`'s `constraintEqualToSystemSpacingAfter(_:multiplier:)` 222 | ```swift 223 | override func viewDidLoad() { 224 | let greenView = UIView() 225 | greenView.backgroundColor = .green 226 | view.addSubview(greenView) 227 | greenView.translatesAutoresizingMaskIntoConstraints = false 228 | greenView.topAnchor.constraintEqualToSystemSpacingBelow(view.topAnchor, multiplier: 1).isActive = true 229 | greenView.leadingAnchor.constraintEqualToSystemSpacingAfter(view.leadingAnchor, multiplier: 1).isActive = true 230 | view.trailingAnchor.constraintEqualToSystemSpacingAfter(greenView.trailingAnchor, multiplier: 1).isActive = true 231 | view.bottomAnchor.constraintEqualToSystemSpacingBelow(greenView.bottomAnchor, multiplier: 1).isActive = true 232 | 233 | let magentaView = UIView() 234 | magentaView.backgroundColor = .magenta 235 | view.addSubview(magentaView) 236 | magentaView.translatesAutoresizingMaskIntoConstraints = false 237 | view.layoutMarginsGuide.topAnchor.constraint(equalTo: magentaView.topAnchor).isActive = true 238 | view.layoutMarginsGuide.leadingAnchor.constraint(equalTo: magentaView.leadingAnchor).isActive = true 239 | view.layoutMarginsGuide.trailingAnchor.constraint(equalTo: magentaView.trailingAnchor).isActive = true 240 | view.layoutMarginsGuide.bottomAnchor.constraint(equalTo: magentaView.bottomAnchor).isActive = true 241 | } 242 | ``` 243 | 244 | 245 | 246 | --- 247 | 248 | ### 10. `UIStackView`'s `isLayoutMarginsRelativeArrangement` 249 | ```swift 250 | override func viewDidLoad() { 251 | let stackView = UIStackView() 252 | stackView.isLayoutMarginsRelativeArrangement = true 253 | stackView.distribution = UIStackViewDistribution.fillEqually 254 | view.addSubview(stackView) 255 | stackView.translatesAutoresizingMaskIntoConstraints = false 256 | stackView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true 257 | stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true 258 | stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true 259 | stackView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true 260 | 261 | let redView = UIView() 262 | redView.backgroundColor = .red 263 | stackView.addArrangedSubview(redView) 264 | 265 | let blueView = UIView() 266 | blueView.backgroundColor = .blue 267 | stackView.addArrangedSubview(blueView) 268 | } 269 | ``` 270 | 271 | 272 | 273 | --- 274 | 275 | ### 11. `UIScrollView`'s `contentInsetAdjustmentBehavior` + `UIScrollView`'s `contentInset` + `UIScrollView`'s `contentLayoutGuide` 276 | ```swift 277 | override func viewDidLoad() { 278 | let scrollView = UIScrollView() 279 | scrollView.backgroundColor = .orange 280 | scrollView.contentInsetAdjustmentBehavior = .scrollableAxes 281 | scrollView.contentSize.width = 1000 282 | scrollView.contentInset = UIEdgeInsets(top: 5, left: 5, bottom: 5, right: 5) 283 | scrollView.contentOffset.x = -5 284 | view.addSubview(scrollView) 285 | scrollView.translatesAutoresizingMaskIntoConstraints = false 286 | scrollView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true 287 | view.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true 288 | view.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true 289 | scrollView.heightAnchor.constraint(equalToConstant: 80).isActive = true 290 | 291 | let blueView = UIView() 292 | blueView.backgroundColor = .blue 293 | scrollView.addSubview(blueView) 294 | blueView.translatesAutoresizingMaskIntoConstraints = false 295 | blueView.topAnchor.constraint(equalTo: scrollView.contentLayoutGuide.topAnchor).isActive = true 296 | blueView.leadingAnchor.constraint(equalTo: scrollView.contentLayoutGuide.leadingAnchor).isActive = true 297 | blueView.widthAnchor.constraint(equalToConstant: 70).isActive = true 298 | blueView.heightAnchor.constraint(equalToConstant: 70).isActive = true 299 | } 300 | ``` 301 | 302 | 303 | 304 | --- 305 | 306 | ### 12. `UICollectionView`'s `contentInsetAdjustmentBehavior` 307 | ```swift 308 | import UIKit 309 | 310 | class CyanCollectionViewCell: UICollectionViewCell { 311 | override init(frame: CGRect) { 312 | super.init(frame: frame) 313 | backgroundColor = .cyan 314 | } 315 | 316 | required init?(coder aDecoder: NSCoder) { 317 | fatalError("init(coder:) has not been implemented") 318 | } 319 | } 320 | 321 | class ViewController: UICollectionViewController, UICollectionViewDelegateFlowLayout { 322 | 323 | let idealCellWidth: CGFloat = 100 324 | let margin: CGFloat = 5 325 | 326 | override func viewDidLoad() { 327 | collectionView?.contentInsetAdjustmentBehavior = .always 328 | 329 | guard let flowLayout = collectionView?.collectionViewLayout as? UICollectionViewFlowLayout else { return } 330 | flowLayout.minimumInteritemSpacing = margin 331 | flowLayout.minimumLineSpacing = margin 332 | flowLayout.sectionInset = UIEdgeInsets(top: margin, left: margin, bottom: margin, right: margin) 333 | 334 | collectionView?.register(CyanCollectionViewCell.self, forCellWithReuseIdentifier: "cell") 335 | } 336 | 337 | override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 338 | return 25 339 | } 340 | 341 | override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 342 | return collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CyanCollectionViewCell 343 | } 344 | 345 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 346 | guard let flowLayout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout else { return .zero } 347 | let availableWidth = collectionView.frame.width - collectionView.safeAreaInsets.left - collectionView.safeAreaInsets.right - flowLayout.sectionInset.left - flowLayout.sectionInset.right 348 | let idealNumberOfCells = (availableWidth + flowLayout.minimumInteritemSpacing) / (idealCellWidth + flowLayout.minimumInteritemSpacing) 349 | let numberOfCells = idealNumberOfCells.rounded(.down) 350 | let cellWidth = (availableWidth + flowLayout.minimumInteritemSpacing) / numberOfCells - flowLayout.minimumInteritemSpacing 351 | return CGSize(width: cellWidth, height: cellWidth) 352 | } 353 | 354 | override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { 355 | collectionView?.collectionViewLayout.invalidateLayout() 356 | super.viewWillTransition(to: size, with: coordinator) 357 | } 358 | 359 | } 360 | ``` 361 | 362 | 363 | 364 | --- 365 | 366 | ### 13. `UITableView`'s `insetsContentViewsToSafeArea` 367 | ```swift 368 | import UIKit 369 | 370 | class Cell: UITableViewCell { 371 | 372 | let label = UILabel() 373 | 374 | override init(style: UITableViewCellStyle, reuseIdentifier: String?) { 375 | super.init(style: style, reuseIdentifier: reuseIdentifier) 376 | 377 | contentView.backgroundColor = .yellow 378 | contentView.addSubview(label) 379 | 380 | label.translatesAutoresizingMaskIntoConstraints = false 381 | label.topAnchor.constraint(equalTo: contentView.layoutMarginsGuide.topAnchor).isActive = true 382 | label.leadingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor).isActive = true 383 | label.trailingAnchor.constraint(equalTo: contentView.layoutMarginsGuide.trailingAnchor).isActive = true 384 | label.bottomAnchor.constraint(equalTo: contentView.layoutMarginsGuide.bottomAnchor).isActive = true 385 | } 386 | 387 | required init?(coder aDecoder: NSCoder) { 388 | fatalError("init(coder:) has not been implemented") 389 | } 390 | 391 | } 392 | 393 | class ViewController: UITableViewController { 394 | 395 | override func viewDidLoad() { 396 | tableView.register(Cell.self, forCellReuseIdentifier: "cell") 397 | tableView.insetsContentViewsToSafeArea = true 398 | } 399 | 400 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 401 | return 10 402 | } 403 | 404 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 405 | let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! Cell 406 | cell.label.text = "Lorem ipsum" 407 | return cell 408 | } 409 | } 410 | ``` 411 | 412 | 413 | --------------------------------------------------------------------------------