Bummer! This is just a preview. You need to be signed in with a Basic account to view the entire video.
Start a free Basic trial
to watch this video
Since we're using a text field for the tags we need to take the users input and extract individual tags
-
0:00
In the last video, we added an image view with a content mode of aspect film.
-
0:05
This means that the image view can scale the image to fill the bounds, but
-
0:08
it has to maintain the aspect ratio.
-
0:11
The reason our photo is really large is because in iOS 11,
-
0:14
which is the SDK we're running against in this course,
-
0:18
table views have self sizing cells enabled by default.
-
0:22
This means that absent any specific height values,
-
0:25
the cell resizes itself to fit all the content.
-
0:28
If this were a dynamic table view, we would need to
-
0:31
implement a delegate method and specify the height of this cell.
-
0:35
Since this is a static table view,
-
0:37
however, we can treat the cell defined in the storyboard scene as a plain old view.
-
0:42
Navigate to the scene, and select the cell in question,
-
0:47
which you might have to do from the document outline, and
-
0:51
then go to the size inspector and set a custom row height of 120 points.
-
0:58
Now if we run it again, The image should fit.
-
1:04
So let's select Camera.
-
1:05
Select an image from the camera roll.
-
1:07
We'll apply a filter to that.
-
1:11
And there we go.
-
1:12
Now we have an issue here.
-
1:13
It's obviously not fitting.
-
1:16
So what we might need to do is select the image and
-
1:21
select Clip to Bounds to make it fit.
-
1:25
Okay, let's do that again.
-
1:28
And now we select Camera.
-
1:32
Go through the same process.
-
1:36
Okay, there we go.
-
1:38
Now let's add the rest of our UI in.
-
1:41
So back in our table view we'll zoom in so we can see this better.
-
1:46
Next we want to allow the user to enter a caption.
-
1:50
So let's add add a text field to this first row.
-
1:53
Pin the top of the TextView to the top of the ImageView.
-
1:56
And you can do that by Ctrl+dragging and selecting Top.
-
2:00
And we're also going to pin the bottom edges or align them rather and
-
2:06
then give it a leading and trailing constraint, leading and
-
2:10
trailing space constraint of 8 points.
-
2:14
This should make it fit the area we want.
-
2:17
Let's make a few more tweaks though to improve the appearance.
-
2:20
Give it a placeholder text of Enter a caption.
-
2:25
Set the border style to none over here, and then under Control,
-
2:30
which if you keep scrolling down, there's a section labeled Control here.
-
2:34
In this vertical section, we're going to set it to top and
-
2:37
that puts the text right at the top, okay?
-
2:41
For the second row, let's add a text field, just drop it right in, and a label.
-
2:48
We're going to set the label's text to Tags.
-
2:53
We will center it vertically in the container and give it a leading space
-
2:58
constraint of 0 points and make sure you select Constraint to margins, okay?
-
3:04
Or you could not select Constraint to margins and then set it to 16 points.
-
3:09
That's some nuances there to the difference between those two but
-
3:11
it'll position it in the same place.
-
3:13
Okay, left align the text in the text field,
-
3:17
let's give it a placeholder text of something like beach, sand, sun...
-
3:24
We'll set the border to none again.
-
3:26
We're going to give it a leading and trailing space constraint of 8 points.
-
3:34
And then we'll vertically center in the container and that should be everything.
-
3:40
Now if you run the app you might notice that the caption image positioning doesn't
-
3:44
look the best.
-
3:45
And that's because we're not taking care of the finer points here.
-
3:48
Ideally we'd crop this image so that when it's square,
-
3:51
there's no white space on top depending on the image we select.
-
3:55
And we could give it a subtle border to distinguish between the background.
-
3:58
Well, no big deal.
-
4:00
Now we'll switch to the assistant editor.
-
4:04
Okay, look at that.
-
4:05
It brought up the PhotoMetadataController.
-
4:07
Let's create two outlets for the two text fields.
-
4:11
So first one, we already have an outlet for the image view.
-
4:14
We'll call this captionTextField, and
-
4:19
then the second one, we'll call it tagsTextField.
-
4:25
Getting the caption text is straightforward,
-
4:27
we'll just assume that user wants to save the entire string they type in over there,
-
4:31
so we're not gonna change anything.
-
4:33
Now for the tags, we're to do a tiny bit more work.
-
4:36
We're going to assume here that the user will enter different words separated
-
4:41
by commas like we've entered in the placeholder text.
-
4:44
When we hit Save, we'll get the entire string from the text field,
-
4:47
split it up into each word and then create individual tag objects out of it.
-
4:52
We're going to write a method that takes whatever text is in this text-field and
-
4:56
creates an array of strings where each value is going to be an individual tag.
-
5:00
So let's do that in the PhotoMetadataController,
-
5:03
and we'll do that as an extension.
-
5:07
Right here, so we'll say extension PhotoMetadataController,
-
5:14
and we'll call this method tags(from text: String).
-
5:19
And again, this is going to return an array of String.
-
5:24
We're going to assume that this text contains all the tags
-
5:28
as comma separated strings, so we need to split it up.
-
5:32
Now really, if we were doing this properly,
-
5:34
we would validate that there is actually some text and
-
5:37
handle this, or make sure that the user has entered commas, maybe they haven't.
-
5:41
Lots of things to take care of.
-
5:42
But here we're gonna keep it simple, so we'll say let commaSeparatedStrings
-
5:48
= text.split.
-
5:51
And the separator here is a comma.
-
5:54
And this now if you Option+click,
-
5:57
you see that it returns an array of string.subSequence or a substring.
-
6:01
We want actual strings out of that, so we'll map over this resulting array and
-
6:05
we'll pass each value to the string's init method.
-
6:08
And that should create a string out of each one
-
6:11
which results in an array of strings.
-
6:14
Okay, now this would be sufficient but we wanna clean up a few things.
-
6:17
When we start typing out tags, as you may notice,
-
6:20
the system is going to auto-capitalize that first tag.
-
6:23
It will also do this for certain proper nouns, so if you tag it with your name for
-
6:27
example.
-
6:28
We want to make sure that we store all our tags as lowercase strings.
-
6:32
This way if we create a, say, Beijing tag with an upper case B or
-
6:36
a lowercase b, they both get saved as the same tag and not two different ones.
-
6:40
So here we'll say let lowercaseTags = commaSeparatedStrings.map and
-
6:47
here we'll say $0.lowercased.
-
6:51
Let's clean up one more thing.
-
6:53
Typically when writing out sentences in certain languages,
-
6:56
we put a space after the comma.
-
6:58
This means that if we had two tags, beach and fun, where fun is the second tag.
-
7:03
When we split them up by a comma,
-
7:05
the second string will include a space as its first character.
-
7:09
So we'll get rid of all of this white space and
-
7:11
new line characters as the final thing before we return our array.
-
7:14
So here we'll say, return lowercaseTags.map, and
-
7:18
in this closure we'll say $0, which is each of those strings,
-
7:23
trimmingCharacters(in: CharacterSet) .whitespacesAndNewlines.
-
7:30
Okay, perfect.
-
7:32
To use this method, we'll call it from viewDidLoad up here.
-
7:36
In this app, it's not mandatory to add tags to a photo,
-
7:40
so we'll use an if let to check if there is text in the text field.
-
7:44
So if let tagsText = tagsTextField.text.
-
7:52
Now if there is, we'll say self.tags,
-
7:55
a property that doesn't exist yet, tags(from: tagstext).
-
8:01
Okay, so if there is text, we'll call the method and
-
8:03
we'll assign the resulting tags to a stored property.
-
8:06
We also need to define the stored property, which is an array of strings,
-
8:10
and we'll just give it an empty array initially.
-
8:12
So var tags = an empty array of Strings.
-
8:18
Okay, now we have a caption and a tag but
-
8:21
not the main image with the filter applied.
-
8:24
That's the last thing we need to have ready before we can save.
-
8:27
Let's tackle that in the next video.
You need to sign up for Treehouse in order to download course files.
Sign up