Fashion Low Profile Bed Frame Sku: Fb3056
Update note: Kevin Colligan updated this tutorial for Xcode 10, iOS 12 and Swift 4.2. Joshua Greene wrote the original.
If you've always created custom table view cells before, chances are skillful that you have spent a lot of time sizing table view cells in code. You may fifty-fifty be familiar with having to calculate, manually, the height of every characterization, image view, text field — and everything else within the cell.
Bluntly, this approach is mind-boggling and error prone. In this self-sizing table view cells tutorial, y'all'll learn how to create and size table view cells dynamically to fit their contents. You might be thinking: "That'south going to have a lot of piece of work!" Nope! :]
This tutorial assumes you have a basic familiarity with Auto Layout and UITableView
.
Getting Started
Back in the days of iOS 6, Apple introduced a wonderful new technology: Auto Layout. Developers rejoiced; parties commenced in the streets; bands wrote songs to celebrate its greatness…
OK, and so that might be a stretch, simply information technology was a large deal.
While information technology inspired hope for developers, Car Layout was still cumbersome. Handling Car Layout manually was, and yet is, a smashing example of the verbosity in iOS evolution. Interface Builder was also initially quite inefficient when setting up constraints.
Flash frontward to now. With all the improvements to Interface Builder, it's easy to utilise Car Layout to create self-sizing table view cells!
A few ins-and-outs aside, all you really accept to do is:
- Utilise Car Layout for the UI elements inside the table view cells.
- Gear up the tabular array view
rowHeight
toUITableViewAutomaticDimension
. - Ready the
estimatedRowHeight
or implement the top estimation delegate method.
But you lot don't want to delve into theory right now, practise you? Y'all're set to go down to coding — so go to business organisation with the project.
Tutorial App Overview
Imagine that y'all take a moving-picture show-crazy client who wants an app to bear witness off a number of favorite moving-picture show directors and some of their almost prominent work. Not just any directors, really, just their favorite auteurs.
"Auteurs?" you inquire, "That sounds French."
Oui, it is. The auteur theory of picture making arose in French republic in the 1940s and it basically ways that the director is the driving creative force behind a film. Non every director is an auteur — merely the ones who postage stamp each flick with their private styles. Retrieve Tarantino or Scorsese. And not everyone agrees with this theory — don't go your screenwriter friend started. Merely, the client is always right, so you're ready to outset rolling.
There's one trouble: "We started making the app, but we're stumped at how to display the content in a table view," your customer admits. "Our table view cells have to resize (gulp!) dynamically! Can you get in work?"
Y'all suddenly feel the urge to don a spiffy beret and start shouting orders!
But you don't need gimmicks to be your client's iOS auteur — your programming skills will suffice!
Start, download the "client's code" using the Download Materials button at the top or bottom of this tutorial. Aggrandize the cipher file and open the Auteur-starter project. (Spoiler alert: You lot tin as well open the final Auteur projection to come across what this app will look like once you've finished.)
In the Auteur-starter projection, open Chief.storyboard in the Views group under the Auteurs projection. You lot'll run across three scenes:
From left to correct, they are:
- A elevation-level navigation controller.
-
AuteurListViewController
shows a list of auteurs. -
AuteurDetailViewController
displays the auteur's films and information about each movie.
Build and run. You lot'll see the AuteurListViewController
displaying a list of auteurs. Select the beginning auteur, Wes Anderson. The app will segue to the AuteurDetailViewController
to display a listing of the selected auteur's films:
Not only is the app missing images of each auteur and each flick, the information you are trying to display is as well cut off! Each piece of data and image will exist a unlike size, then you lot can't just increase the tabular array view cell height and call it a wrap. Your jail cell heights will need to exist dynamic, based on the content of each cell.
Yous'll get-go by implementing the dynamic cell heights in AuteurListViewController
.
Creating Self-Sizing Table View Cells
To get dynamic cell heights working properly, you lot need to create a custom table view cell and gear up it up with the right Auto Layout constraints.
In the projection navigator, select the Views group and press Command-Due north to create a new file in this group. Create a new Cocoa Touch Class, called AuteurTableViewCell, and get in a subclass of UITableViewCell. Brand sure Too create XIB file is unchecked and that the language is prepare to Swift.
First, open AuteurTableViewCell.swift. Then, delete the 2 automatically generated methods and add the following holding:
@IBOutlet weak var bioLabel: UILabel!
Next, open Main.storyboard and select the cell in the tabular array view of the Auteurs scene. In Identity inspector, change Class to AuteurTableViewCell:
Drag and drop a new UILabel
onto the jail cell, and set the text to Bio. Set the new characterization's Lines belongings (the number of lines the label can have at most) to 0 in the Attributes inspector. It should look like this:
Setting the number of lines is very important for dynamically sized cells. A label with its number of lines prepare to 0 volition grow based on how much text it is showing. A label with number of lines prepare to whatsoever other number volition truncate the text one time it'due south out of available lines.
Connect the bioLabel
outlet of AuteurTableViewCell
to the characterization on the cell. One quick mode to exercise this is to right-click the Jail cell in the Document Outline, and click-drag from the empty circumvolve to the correct of bioLabel under the Outlets listing in the pop-up card to your characterization that you lot laid out:
The trick to get Auto Layout working on a UITableViewCell
is to ensure that y'all accept constraints to pin each subview on all sides — that is, each subview should have leading, top, trailing and bottom constraints. Then, the intrinsic height of the subviews will be used to dictate the tiptop of each jail cell. You'll practise this now.
Note: If you're not familiar with Auto Layout, or you would similar a refresher to understand how to fix Auto Layout constraints, accept a look at this tutorial.
Select the bio label and press the Pin button at the bottom of your storyboard. In this menu, select the four dotted lines towards the meridian of the menu. Next, modify the leading and trailing values to 8 and click Add together Constraints. It will look similar this:
This ensures that, no matter how big or pocket-size the jail cell may exist, the bio label is always:
- 0 points from the meridian and lesser margins.
- viii points from the leading and trailing margins.
Review: Does this satisfy the previous Machine Layout criteria?
- Does each subview accept constraints that pivot all of their sides? Yes
- Are in that location constraints going from the top to the lesser of the contentView? Yes
The bio label is connected to the summit and lesser margins by 0 points, so Automobile Layout can now determine the height of the prison cell!
Crawly, your AuteurTableViewCell
is ready! If y'all build and run the app now, you'll meet that…
…whoa, that's not right! Cutting!
There's a bit of code you need to write earlier the cells tin can get dynamic.
Configuring the Table View
First, you need to configure the table view to utilise properly your custom cell.
Open AuteurListViewController.swift (in the ViewControllers group) and supercede tableView(_:cellForRowAt:)
with the following:
func tableView( _ tableView: UITableView, cellForRowAt indexPath: IndexPath ) -> UITableViewCell { let prison cell = tableView.dequeueReusableCell( withIdentifier: "Cell", for: indexPath) equally! AuteurTableViewCell permit auteur = auteurs[indexPath.row] prison cell.bioLabel.text = auteur.bio cell.bioLabel.textColor = UIColor(reddish:0.75, light-green:0.75, blue:0.75, alpha:1.0) return jail cell }
The lawmaking above is pretty straightforward: Y'all dequeue a cell, set up its information with a text color and return the jail cell.
In AuteurListViewController.swift, add these two lines of code at the lesser of viewDidLoad()
:
tableView.rowHeight = UITableView.automaticDimension tableView.estimatedRowHeight = 600
When you gear up the row height every bit UITableViewAutomaticDimension
, the table view is told to use the Automobile Layout constraints and the contents of its cells to make up one's mind each cell's acme.
In order for the tabular array view to do this, y'all must besides provide an estimatedRowHeight
. In this case, 600 is just an arbitrary value that works well in this particular instance. For your own projects, you should pick a value that improve conforms to the type of data that you'll display.
Build and run, and yous should at present see all of each auteur's bio.
That looks better! But practise you know what would make this app even more dramatic? A moody nighttime background.
Open Main.storyboard, select the cell in the table view of the Auteur scene. In the Attributes inspector find the Background colour drib-down menu:
Click Groundwork and select Custom. In the window that pops upwardly, select the RGB Sliders tab and, in the Hex Colour # field, enter 161616 — this volition give you a nice black-ish background (pure black is not cool enough for auteurs :]).
Press Return; build and run your app. It should look like this:
Such drama!
Calculation Images
It'southward nice that you tin now read the entire bio of each artist, simply in that location is still more data to prove. Each artist has an epitome and a name. This app uses an external API to retrieve the information, so there'due south a source characterization as well. Using these additional pieces of information will make the app look much better.
You will need to add an image view to AuteurTableViewCell
, and another label for the auteur'south name. You lot should also add a source characterization to properly credit the photograph. Open AuteurTableViewCell.swift and add the following properties:
@IBOutlet weak var nameLabel: UILabel! @IBOutlet weak var source: UILabel! @IBOutlet weak var auteurImageView: UIImageView!
Note: The image view's variable name is auteurImageView
rather than imageView
because at that place is already an imageView
property on UITableViewCell
.
Now, adjust the bio label. It's tough to run across in the Principal.storyboard with the night prison cell background. Open Main.storyboard, select the bio label and choose a lighter color for the text.
Annotation: It really doesn't matter what y'all set the bioLabel
color to in Primary.storyboard because this code from AuteurListViewController.swift will override it at runtime:
cell.bioLabel.textColor = UIColor(red:0.75, greenish:0.75, blue:0.75, alpha:one.0)
Now, remove the constraints from bio characterization so that you can add more elements to the cell and shift things effectually. In the Document Outline, notice the Constraints nether Bio Label. Select each of the four constraints (hold the Shift cardinal to select them all) and printing Delete. Ignore any Motorcar Layout warnings for now.
Before you add more than elements, you'll need some elbow room. Select the Cell from the Certificate Outline. So, in the Size inspector, modify the Row Height to 450.
Now, you'll fill up upward that space:
- Drag an ImageView into the jail cell.
- Drag a Label into the prison cell. And so, set its text to Proper name and its color to white.
- Drag another Label into the cell. Then, prepare its text to Source, its Font to System 13.0 and its color to white.
Move the elements in the post-obit order, from top to bottom (you'll add constraints in a before long):
- ImageView
- Proper name
- Bio
- Source
Adjacent, connect the outlets for the new image view and labels, using the same technique you used for the bio label:
Now, it's time to setup more constraints. Starting with the source label moving up, apply the Pin card to add these vertical constraints:
- Pin the bottom edge of the source label to sixteen points from the superview.
- Pin the top edge of the source characterization to eight points from the bottom of the bio label.
- Pin the top edge of the bio label to 8 points from the lesser of the proper noun label.
- Pin the top edge of the name label 8 points from the lesser of the image view.
- Pin the top border of the paradigm view 0 points from the pinnacle of the content view.
At present, add together horizontal constraints. Start, apply the Pin bill of fare to:
- Pin the leading edge of the name label to 8 points from the superview.
- Pivot the abaft edge of the name label to 8 points from the superview.
- Shift-Click the name label, bio characterization and source label and choose Equal Width from the Pin menu.
- Set the image view to take a height and width of 300 points.
Then, use the Align carte du jour to center all items:
- Shift-click the epitome view, name label, bio label and source label and choose Horizontally in Container from the Marshal carte du jour
Finally (well, nearly), you demand to ready the hugging vertical priorities for the name label and bio label. Select the nameLabel in the Size inspector and scroll downwardly until you see Content Hugging Priority. Horizontal and Vertical will both exist set up to 251 by default. Change the name label's Vertical priority to 253.
At present, select the bio label and set its Vertical priority to 252, and yous're washed with the storyboard for now.
Note: Await, what's with all the hugging? Is this a romance picture?
Not exactly. Setting a higher priority on content hugging means that the view will resist growing larger than its intrinsic size. You told the storyboard to make your cell with 450 points tall, which is larger than the intrinsic size of your views. Setting a vertical content hugging priority tells Xcode which view to expand if it needs to fill the infinite.
Open AuteurListViewController.swift and add the post-obit two lines of code to tableView(_:cellForRowAt:)
, afterwards you set the bioLabel
's text:
jail cell.auteurImageView.image = UIImage(named: auteur.paradigm) cell.nameLabel.text = auteur.name jail cell.source.text = auteur.source
And so, add these lines after you set the textColor
:
jail cell.nameLabel.textColor = .white cell.bioLabel.textColor = UIColor(red:0.75, green:0.75, blue:0.75, alpha:1.0) cell.source.textColor = UIColor(cherry:0.74, greenish:0.74, bluish:0.74, alpha:1.0) cell.source.font = UIFont.italicSystemFont(ofSize: cell.source.font.pointSize) cell.nameLabel.textAlignment = .heart cell.selectionStyle = .none
Build and run your app.
Looks pretty good. But auteurs aren't square, then allow's tweak tableView(_:cellForRowAt:)
to add the following lawmaking just before render cell
:
cell.auteurImageView.layer.cornerRadius = cell.auteurImageView.frame.size.width / 2
Then, head dorsum to Main.storyboard and select the prototype view. Then, select the Prune to Premises option in the Attributes inspector:
Build and run your app again to see your auteur images in a circular frame fit for the MGM lion:
You're just about done with constraints on the AuteurListViewController
, just eagle-eyed readers may have noticed Xcode throwing upward a alarm.
If you click on the warning, you'll get more information. It turns out that the layout works fine in English, but y'all may have bug if y'all localize your app to use a language that reads from right to left.
Xcode offers to fix the problem. Merely you can exercise it yourself past adjusting 1 of the name label constraints. Head back to Chief.storyboard and select the name characterization. In the Size Inspector, find the Abaft Infinite constraint and click Edit.
Modify the operator from equal to greater-than or equal.
And the Xcode alarm is gone!
Creating Dynamic Height
If you recall from the outset, selecting an auteur presents a view controller that shows the selected auteur's films. The cells in this table view will demand to take dynamic height also.
The first step, just like before, is to create another bracket of UITableViewCell
.
In the project navigator select the Views group and press Command-N to create a new file in this group. Create a new Cocoa Touch Class called FilmTableViewCell and go far a subclass of UITableViewCell.
Open FilmTableViewCell.swift and, like before, delete the 2 automatically generated methods in FilmTableViewCell
then add these backdrop:
@IBOutlet weak var filmImageView: UIImageView! @IBOutlet weak var filmTitleLabel: UILabel! @IBOutlet weak var moreInfoTextView: UITextView!
Open up Chief.storyboard and select the cell in the table view in the Auteur Item View Controller scene. Set the Custom Class of the cell to FilmTableViewCell, and then alter the row elevation to 300 to give yourself enough of room to piece of work with.
Now, elevate out an Image View, a Label and a Text View. Place them as pictured beneath (the text view is on the very bottom):
Change the text of the text view to Tap For Details > and the characterization to Name. Alter the mode of the prototype view to Aspect Fit. Select the text view, in the Attribute inspector. And then, change its alignment to Centered, fix the text colour to Ruby-red and disable scrolling:
Disabling scrolling is of similar importance to setting a label to 0 lines. With scrolling disabled, the text view knows to abound its size to fit all of its content, since the user won't be able to scroll through the text.
A bit further down past where y'all disabled scrolling, remove the check from User Interaction Enabled. This volition permit touches to laissez passer through the text view and trigger a selection of the cell itself. Then, set the groundwork color to Clear Color.
Now, select the cell in Auteur Particular View Controller scene and set the background to the Hex Color #161616, simply as you did on the Auteur scene. Select the name label and ready the text color to white, then you tin can see it on the Main.storyboard.
Connect the three elements with their corresponding outlets, as you did with the first cell.
Now, you'll add constraints. Starting with the text view and moving up:
- Pivot the bottom edge of the text view 0 points from the bottom margin of the content view.
- Pin the leading and trailing edges of the text view 8 points from the leading and trailing margins of the content view.
- Pin the top edge of the text view 8 points from the bottom of the label.
- Pivot the top edge of the label eight points from the lesser of the epitome view.
- Center the proper noun label past choosing Horizontally in Container in the Marshal carte.
- Select both the name label and epitome view (using Shift-click) and choose Equal Widths from the Pivot menu.
- Pin the top edge of the epitome view 0 points from the top margin of the content view.
- Pin the leading and trailing edges of the image view eight points from the leading and trailing margins of the content view
You're done with the storyboard for now. Just every bit you lot had to do with the previous view controller, dynamic prison cell heights have a bit of lawmaking as well.
Open AuteurDetailViewController.swift and replace tableView(_:cellForRowAt:)
with the post-obit:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView .dequeueReusableCell(withIdentifier: "Cell", for: indexPath) every bit! FilmTableViewCell permit film = selectedAuteur.films[indexPath.row] cell.filmTitleLabel.text = film.title prison cell.filmImageView.epitome = UIImage(named: film.poster) cell.filmTitleLabel.textColor = .white cell.filmTitleLabel.textAlignment = .heart cell.moreInfoTextView.textColor = .blood-red prison cell.selectionStyle = .none render cell }
This should look very familiar by at present. You are dequeuing and casting your prison cell, getting a reference of the model struct you are going to display and and so configuring your jail cell earlier you return it.
Now, in viewDidLoad()
of the same grade, add together the following code to the end of the method:
tableView.rowHeight = UITableView.automaticDimension tableView.estimatedRowHeight = 300
Build and run your app. Click through one of the auteurs to run across their films.
Slap-up, merely have it to the adjacent level past adding expanding cells to reveal more info almost each work. Your client is going to honey this!
Expanding Cells
Since your jail cell heights are driven past Auto Layout constraints and the content of each interface element, expanding the cell should be as simple as adding more text to the text view when the user taps that cell.
Open AuteurDetailViewController.swift and add the post-obit extension:
extension AuteurDetailViewController: UITableViewDelegate { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { // 1 guard let cell = tableView.cellForRow(at: indexPath) as? FilmTableViewCell else { return } var movie = selectedAuteur.films[indexPath.row] // 2 film.isExpanded = !film.isExpanded selectedAuteur.films[indexPath.row] = film // 3 cell.moreInfoTextView.text = flick.isExpanded ? film.plot : moreInfoText cell.moreInfoTextView.textAlignment = flick.isExpanded ? .left : .centre cell.moreInfoTextView.textColor = film.isExpanded ? UIColor(scarlet:0.75, green:0.75, blue:0.75, blastoff:1.0) : .red // 4 tableView.beginUpdates() tableView.endUpdates() // five tableView.scrollToRow(at: indexPath, at: .peak, blithe: true) } }
Here'southward what'south happening:
- You ask the
tableView
for a reference of the cell at the selectedindexPath
then to get the correspondingFilm
object. - You toggle the
isExpanded
country of theMoving-picture show
object and add it back into the array, which is necessary since structs are value types. - Side by side, you alter the text view of the cell, depending on whether the work is expanded. If it is, y'all set the text view to brandish the film'due south info property. You also change the text alignment to
.left
and its color to light gray. If it isn't expanded, you set the text back to "Tap for Details >", the alignment dorsum to.center
and the color back to ruddy. - The table view needs to refresh the prison cell heights at present. Calling
beginUpdates()
andendUpdates()
will force the tabular array view to refresh the heights in an animated mode. - Finally, yous tell the tabular array view to scroll the selected row to the top of the table view in an blithe style.
Now in tableView(_:cellForRowAt:)
, add the post-obit three lines at the end, before you return the cell:
cell.moreInfoTextView.text = film.isExpanded ? film.plot : moreInfoText prison cell.moreInfoTextView.textAlignment = film.isExpanded ? .left : .center jail cell.moreInfoTextView.textColor = film.isExpanded ? UIColor(ruby:0.75, green:0.75, bluish:0.75, alpha:i.0) : .cerise
This lawmaking volition cause a prison cell that is beingness reused to correctly call up if it was previously in the expanded land.
Build and run the app. When you tap a motion picture cell, yous'll run across that information technology expands to accommodate the full text. But the image animates a scrap weirdly.
That won't exist hard to fix! Open Main.storyboard, select the image view in your FilmTableViewCell
and open the Size inspector. Alter the Content Hugging Priority and Content Pinch Resistance Priority to the values pictured below:
Setting the Vertical Content Hugging Priority to 252 will aid the image view to hug its content and not to get stretched during the animation. Setting the Vertical Compression Resistance Priority to thousand prevents the image from being compressed if other interface elements abound effectually it.
Build and run the app. Select an auteur and tap on the films. You should come across some very smooth jail cell expansion, revealing information near each pic.
Implementing Dynamic Type
Y'all've shown your progress to your client and they are loving it! Merely they take ane concluding asking. They want the app to support the Larger Text Accessibility feature. The app needs to adjust to the client'south preferred reading size.
Introduced in iOS 7, Dynamic Type makes this task easy. Information technology gives developers the ability to specify different text styles for unlike blocks of text (like Headline or Body) and accept that text adjust automatically when the user changes the preferred size in device Settings.
Caput back to Chief.storyboard and the Auteurs scene. Select the proper name label and, in the Attributes inspector, complete the post-obit steps:
- Click the "T" icon in Font.
- Select Headline from under Text Styles.
- Check the Automatically Adjusts Font box
- Set the Lines to 0.
Do the same with the bio label, but cull Torso under Text Styles instead of Headline.
On the Auteur Detail View Controller scene, take the same steps with the proper noun characterization, setting its Text Style to Headline. Set the text style of the Text View to Trunk (there is no Lines adjustment since this isn't a characterization).
That'south all you need to do to make the app more than accessible. Build and run your app.
Click the Dwelling house button on your simulator and open the Settings app, then click General ▸ Accessibility ▸ Larger Text and drag the slider to the right to increase the text size to a large setting:
And so, go back to the Auteurs app' your text should at present appear larger. Thanks to your work on getting the dynamically sized cells, the tabular array view even so looks keen:
Where to Go From Here?
Congratulations on completing this tutorial on self-sizing table view cells!
You tin can download the completed version of the project using the Download Materials push at the top or bottom of this tutorial.
Tabular array views are perhaps the most primal of structured data views in iOS. Every bit your apps get more complex, you lot're likely to apply all sorts of custom table view cell layouts. You can delve deeply into Auto Layout in the Mastering Auto Layout video form.
If you have whatever comments or questions, delight respond below!
0 Response to "Fashion Low Profile Bed Frame Sku: Fb3056"
Post a Comment