 Welcome, thank you and welcome everyone. So welcome to this talk. My name is Zhijing. I'm working as an iOS engineer at Shopee. So today, we'll be taking a look at how we could adapt our apps to iPhone X. And if you have added iPhone X support to your apps, we would also like to know the approaches you guys took. So feel free to share with us after this talk, all right? So just give me a second. I need to adjust this just a little bit. So very quickly. It seems that our projector didn't adjust its layout just not properly. Anyway, that's us. So for tonight, we'll start with taking a look at what is new on iPhone X. And then we'll talk about some design changes followed by some UIX guidelines, both from Apple itself, officially, as well as from the community, right? So in the end, we'll talk about some issues, tips, and tricks that we have found during our adaptation to the iPhone X. So start with what is new. At the first glance, there is this brand new edge to edge screen, but not exactly edge to edge. So it has new size and new shapes. So Apple has given this name of super random display. And it seems to me that Apple has run out of names. So I'm super, super looking forward. What's the next name for the next generation of displays? Just a sec. So let's take a closer look at this display. So it is 5.8 inch and features a 558 ppi, and which is the highest in its lineup. And then we also realize that something actually is missing, is the home button. So Apple has replaced the home button with this indicator. It's the tiny little horizontal bar beside it has the bottom of the screen. So with it, Apple has introduced a bunch of new gestures. For example, you can swipe up. And then if you don't let go of your finger, then you will go to the edge feature. And if you go all the way up, then you'll go back to the home screen like this. And also, you can switch, if you swipe horizontally, you can switch to the adjacent apps just like this, very, very convenient. And we also notice that something else is missing. It's a tiny little area in a center, top center on the screen. So this is called the sensor housing. Inside it is a whole bunch of projectors, cameras, sensors basically, which is quite compact. And so Apple has also introduced this true depth camera, so which is basically a projector, a front camera, an infrared camera, and a flood illuminator. So with this, we are able to do Face ID. It's a new way of doing authentication, of unlocking your phone and also give authentication to the apps. So to me, I feel that this new way of authentication is quite smooth because it is purely automatic. The moment I want to unlock my phone, or if I want to log into my app, for example, my banking app or whatever, so I don't even need to do anything. It's fully automatic, it's fully transparent. It feels as if there's no authentication at all, but actually it works. So that's my personal feeling, but some people, some are lost, might not think so. Some people might have slight difficulty in using this feature. And of course, I hope that I never had a chance to use this, this way, all right? So now, true depth camera also give us this new feature called animo G, whereby our facial movements can be tracked properly and projected or replayed on another object. In this case, it's a cute little panda. So we can do more things with it. So Apple has improved the ARKit to enable us to do face tracking. So with this, we have four new capabilities to play around. So the first one is the face detection and positional tracking. So basically you'll be able to know the face as well as the positional, all the positional information. And also, most importantly, with this ARKit, we are able to get the information of around 50 muscle movements. And with those information, we can do a lot of fancy stuff. And of course, most importantly, it is in real time. So which comes in handy. So on top of that, we can also have two images. One is a color image, traditionally, and the other one is the friend's depth image. This is really interesting because so now we are able to get the depth information. That means we can know which, how far is each object away from the camera? So if you want to do some further optimization, further rendering, it's very, very helpful. Then last but not least, this ARKit also use our face as a light probe to understand the lighting condition. So if you want to do something like animal G and then you're able to get the lighting information of the environment as well as the face, so if you replay it to some other objects, then it's going to look very real and blend into the environment naturally. All right, so behind the scene inside the core is the new A11 neural engine. So what's a neural engine? Basically, it's a dedicated piece of hardware to run some specific machine learning algorithms which makes it quite powerful in terms of machine learning. And it features this dual-core design and 600 million operations per second. Operate speed, okay? So with that, we are able to play more with SDKs. So we can do augmented reality. It's been further enhanced in iOS 11 and we can do machine learning as well as advanced graphics processing. So we are not going to get too deep into these topics and there's a whole bunch of topics and resources online. So if you're interested, you can go read them out, right? So this is a complete list from the WWC, one of these from the echo schedule events, right? So let's take a look at some key design changes. So this should be something that we are more interested in. So first thing, the design assets. So now all the design assets on iPhone X is using three X designs. So if you've been using three X, then you don't need to do anything special. But moving forward, Apple suggests us to use vector-based assets, for example, PDF. Yeah, so let's say in the future, Apple introduces some other devices with four X or five X, then you don't need to do anything special, right? So this is Apple's suggestion and it also gave us a few examples, example assets for us to download and explore, right? So let's take a closer look at the screen. So basically it's 375 points width and 812 points in height. And if rendered in three X, it will be this amount of pixels. And compared to the 4.7 inch, it is 145 point taller, which is 20%, around 20% taller, right? So we're designed for the iPhone X, so definitely you can put more stuff in one scroll, right? So let's take a look at the top sensor housing. It seems that its corner radius is not cropped, it's not cropped out of no reason. There seems to be some artistic principles behind it. So of course, it is still a compromise, right? It's still not a perfect solution, but this is definitely not the easiest solution Apple has made. One easier solution would be instead of having this top notch, they can just put one additional horizontal black border on top of the display. So they can put all the sensors in the additional border, top border, but they didn't. So obviously they did this for a reason. So there's a whole lot of debates and conversations online. So I'm not an artistic person, so I'm not going to talk too much about it. So as developers, when we're doing, adapting the layout to iPhone X, we care more about the specific metrics. So here it is, the cheat sheet. So looking at it, we realize that there is a 44 point status bar, followed by a 99% navigation bar. And at the bottom, you have a 49 point tag bar and 34 point home indicator. So as developers, we need to keep this in mind because when we develop it, we need to measure against the designs. But this is only for debugging purposes. We should never hard-code those values because we never know in the future what new metrics or what new numbers will be there. So never use these magic numbers in your code only for debugging purposes, all right? So now let's take a look at the system UI. And it seems that all the system UIs automatically adjust itself in iPhone X without you doing anything. For example, in a case of navigation bar, you can see that the background will basically flood all the way to the edge of the screen. And the same goes for the bottom tag bars. So you don't need to do anything. And for the horizontal content, Apple has done a lot and a lot of automatic insets, for example, in a piece of table view. The content is automatically inset away from the edge of the screen. And Apple has introduced this safe area. This is the most important topic that I would like to talk about today. And let's take a look. So safe area defined by Apple is the portion of the view that will not be covered by any of the bars or hardware. So you are completely safe if you lay out the stuff inside it, right? So let's look at the screen. So if you don't do anything, your safe area will be defined as the entire screen. And if you have to have a status bar, then the safe area will be streamed to the bottom a little bit. And we have a navigation bar, which will be shrinking further. And if you have a tag bar, in the case of the last screenshot, your safe area will be shrinked from the bottom edge, right? So in a piece of iPhone X, the safe area comes even more handy. So it automatically avoids all those areas that may get hidden, right? For example, the bottom call mediator and the center housing on the top. So, and this is also, this also holds in the case of horizontal layout. So your view will be automatically inset from the edge of the screen if you are using safe area, right? And also we have the good old layout margin, which now also respects safe area layout. So if you've been using layout margin, so then you should be in good shape, right? So we'll get back to safe area in just a bit. We'll talk more about it. So before that, I would like to share with you a few UI, UX guidelines based on the changes we have seen just now. And a lot of them are from Apple itself and also some are from the community, right? So the first suggestion would be, whenever possible, we should always provide a full screen experience. What do I mean? So of course the easiest way to adapt your app to iPhone X is to put a blackboarder at the bottom and top of the screen. Then you are done, right? You are safe to go. But this is strongly discouraged because iPhone X is there to provide immersive and full screen experiences. And if your app will somehow look kind of left, then it might look annoying to some of the users, right? So always provide a full screen experience. But at the same time, bear in mind, don't let the real reporters or the center housing block some of your important controls, right? So next, it's called InSat, only when needed. So this is a screenshot from the app that I'm working on, which is Shopee, yeah. So basically it's an online e-commerce platform. Rainer South is Asia. We started in 2015 and it's one of the fastest growing e-commerce platforms in the region. But anyway, this is our app. And so we have basically two screenshots here. The one on the left is a vertically scrollable, infinite scrollable lecture view. And so in this case, it is recommended that you should extend your view all the way to the bottom. Even if it's hidden by the home indicator, it's hidden behind the home indicator, it's completely fine. The reason being that first thing, user can scroll, right? So the common hidden can be brought up if user continue to scroll. And the second reason is that the home indicator doesn't recognize click events. So even if the user click at the bottom row, the user will still be able to get the correct response from your app without interfering by the scroll indicator. So which is fine. The user will see a continuous movement of your content. So in another case, just take a look at the right hand side. So we have some custom bottom toolbars, or sometimes we will just be a very big submit button, right? So in this case, you should never hide those custom views behind the home indicator, because those buttons are not scrollable. They are fixed at the bottom and we don't want to block any important message, right? So that's this rule. And the next suggestion is if you are reusing some of your design artworks, bear in mind that they may be cropped in different sizes of the screen. So they may be cropped or they may have black borders, two sides, or maybe on top and bottom. So you should be really, really careful with that. And if you have to click any content, make sure the content being clicked is irrelevant details. Make sure your main content, your content of interest is always there in the screen, right? So the next suggestion would be be mindful of status bar. So if you look at the status bar, then I realize that the height doesn't change anymore. So I say in the previous case, if the user is maybe talking on the phone or maybe if the user has enabled the personal hotspot, then your status bar height may change, this is no longer the case. Instead, the color will change, right? So if you're doing some custom background color behind the status bar, then you should take extra care because your custom color may conflict with the system's background color. So make sure you design your background color in a way that looks nice, even if the background color of the status bar changed, right? So although the height is fixed, but like I said just now, we shouldn't assume this is the truth in the future. So yeah, and also, hiding the status bar is discouraged because in iPhone 10, we now have a very long screen, so we have less necessity to hide the status bar anymore, right? You have the more content to show and if you cannot see everything, then maybe you can employ a scroll wheel of sorts, right? And of course, it's also a good behavior to show the time, show the battery, and show the whatever information in the status bar to the user. So user can always refer to those informations as and when the user wants, right? So that would be a good experience. So the next suggestion, move controls inside safe area. So I see a lot of control all around your edges. So don't do this because the content of the control may be hidden by the corners and yeah. So make sure you respect this area and you'll get to that in just a minute. So also, next one, be symmetrical. So same example, if you look at this, you'll notice that the left, the buttons on the left have different distances from the left edge on the top screenshot and the bottom screenshot, right? So this design will undermine people's ability to build muscle memories and will confuse people. So your user, your user app, maybe they have to rotate the phone to a specific angle to user app. So inside, what you can do is this, just make it symmetrical. So no matter how the user rotates the phone, your audio controls have a fixed exact, the same distance from the edge of the phone. So which is very convenient for the users, right? Next, leave the home indicator alone. Don't do anything about it, right? So don't put any adornments such as background colors, shapes, bezels, or directional text to draw attention. So this home indicator can do all the things itself. So it's white in dark background and it's dark in white background, right? So just leave it alone. And also, do not add any gesture recognizers at the bottom of the screen because that might go conflict with the home indicator such as your recognizer, right? So next, do not do heavy lifting when ad will be signed about, when ad will be signed active. So with all the new gestures brought by the home indicator, the users can now switch back and forth, switch to the home screen and go back very quickly. And now we also have this control center and notification center, which can be brought up by scrolling from the top of the screen. So your user will, so you will expect, so you will expect a lot of design activities. You know, so don't do any heavy lifting because the user may just come back any time, right? So be careful when you design features. Under this kind of scenarios. Next, reference authentication methods accurately. So because on the iPhone X, we now have this face ID. So the face ID and the touch ID, the previous version is mutually exclusive. So bear in mind that when you are design authentication functionalities, make sure you check all those availability properly, right? And if you support one, it's best that you support the other. And next, allow auto heading of home indicator sparingly. So just now we talked about the same suggestion whereby we shouldn't add any gesture recognizer at the bottom of the screen. But what if my app, I want to create some immersive experiences. I really don't want the home indicator to distract the user's attention. So can I do that? Yes, you can. So there are two ways. One is that you can turn on edge protection. So basically it works like this. So user needs two scrolls to access a home screen. Basically the first scroll will make the home indicator obvious and the second scroll from the bottom will basically bring the user to home. And there's another thing you can do which is the auto hide of home indicator. And so if you do this, if you turn this on, then the home indicator will be automatically hidden completely if the user haven't been interacting with the screen. And if the user touch the screen again, then the home indicator will show again, right? So this is the hiding. And how to do that is very simple. So basically you'll need to override two methods in your view controller. They're top, preferred screen edges, deferring system gestures. This is the edge protection. And the second one will be prefers home indicator auto hidden, right? So that you can just return whatever value you want. And if you want to update the reconfiguration, you can just call this set needs update, blah, blah, blah. So the system will basically involve those configurations again to get the updated value, right? So although this is possible, but still very important that we should always use this very good. So because this user experience is different from all the other apps, so we don't want to confuse a user and then we don't want to add more memory tasks to the user, right? So always use this very good. All right, so now let's talk about some issues as well as some tips and tricks that we have to start when we are doing our apps. And so started by just click the running button in the X code. Then we realize this, right? So this is our app shopping. And the moment we run it in the X code, then we realize this, the app is not running in the full screen. There are indeed black borders on top and on the bottom. So how do we fix that? Very easy. First, build against how it's done in SDK. Second, use launch storyboard and there we go, right? So some people might think that this might be a close approach to force everybody to use the latest SDK, but nonetheless, this should be something we need to do because we should always adapt to the latest technology so that our users can always enjoy all the new functionalities of the apps, right? So in our company, we actually started doing all of these weeks before the launch of iPhone X. So the moment iPhone X is launched, then everybody is able to use the latest, the full screen, the immersive experience on their new phones, right? So we have to launch our app. And the second thing we notice is that, hmm, something still doesn't look right. So you notice under that, we actually, this is the product page whereby we have a customized toolbar at the bottom. So check now, add to cart. And the add to cart text is hidden by the whole menu here. And on the right hand side is our cart page. So basically, we have some very important message, it's the coins message that is hidden. So obviously this is very annoying to our users. So how can we do that? And it turns out that the solution is kind of universal for this kind of problems. So the solution is using safe area. So we've mentioned this twice just now. So now let's take a closer look at how it works and how it works with the other views that we have, right? So some of the ideas is adapted from, is referenced from this blog post and it's kind of a good readout. So if you're interested, you can just take a look. But anyway, let's take a look. Starting with UI views. So how does safe area work with UI view? A simple example will be this. For example, we have two UI labels, one on top and one on bottom. And each of them is attached to the very edge of its super view, just like this, very simple. So then you realize that something's wrong because all your text is running too much, right? So the sensor housing is hidden some and the home indicator is hidden some. Almost as a border line. So how can we do that? Then it turns out that we can do it in two ways. So safe area give us two properties. One is called safe area insights. Okay, let me just go back to these slides. So one is called safe area insights and one is called safe area layout guide. You can reference the first one if you are doing manual calculation and you can reference the second one we are using auto layout, right? Let's go back. Okay, so how do we solve this? So let's take a look at one example of using manual calculation. So in a piece of the top label, what we can do is when we are doing a layout then we can access the views property named safe area insights. So we can attach the X to the safe area insights left and the Y attaching to the safe area insights top and then we can calculate the width with respect to safe area, right? You just manually debug all the insights and then we do the fifth time, right? So what does it look in the case of auto layout? It's actually very simple. So the view has a property safe area layout guide. It has four anchors. What you can do is just you attach the four anchors of your custom view to the anchors of those safe area layout guide like this. Of course, in this case, you still set the height to be a fixed value, right? So then it will look something like this. So you notice that the labels will be inside property and with respect to the safe area. And you also notice something's wrong because you see this orange background color, right? They are not automatically extended to the very bottom and this is not the immersive experience. We certainly don't want this kind of experience. So how can we do it? How can we make the orange color extend all the way to the bottom while we still keep the text like this intact? So one way to do this, of course, is firstly we put the labels into two container views, right? We put a container view at the top and put a container view at the bottom and we put the labels inside. Then the container view will be attached to the super view's edges, right? And then the labels will be attached to the container view's edges, sorry, to the container view's safe area, right? So you can do that by simply doing the first line. So the same error layout that it turns out it has a layout frame. So you can just set your label's frame to be that frame, then you're done. Or if you want to be more explicit, if you want to do more, make our code more understandable, you can use the bottom approach, that are equivalent, right? So this is as good as we use the outer layout to attach the anchors of your far edges. So if you do that, then you'll be done. So now you'll see this, right? Okay, now let's take a look at the safe area with UIViewController. What is the new change in the UIViewController? So it turns out the UIViewController now has a new property with the name of additional area insets. So what does that mean? It is a property for you to tell the system, say, hey, I have my own UIViews, then I want to exclude my views from the safe area. Like for example, you have a custom bottom tab bar, you may have some custom headers, then you want to exclude those. You don't want safe areas to contain these, especially when you are writing some frameworks for other people, right? So just imagine when other people they are using your views, they can just call the safe area. They can just lay out the problems of safe area because the safe area insets has been modified by you using the additional safe area insets, right? And of course, if you set it, then corresponding database will be triggered. In the view state, you'll be safe area inside state change and in the view controller, you'll be view safe area inside state change. So if you are interested or if you want to perform something change of this property, then you should implement those methods or rather you should override this method in your view of your controllers, right? So how about scroll view? So scroll view is, may seems problematic but actually the solution is quite simple. All you need to do is nothing, right? So if you do nothing, in this case, this scroll view is attached to the far edges of the screen so without any insets, without any special handling. So it just works, right? So this is because of this property at the very bottom. The name is a type long, so it's called content-inset-adjustment-behavior. This property is here to replace the good old automatically adjusts your view insets, the one you see on the top. So that one has been definitely in favor of a new problem. So what does this do? This is to help you to specify how can the system help you to automatically adjust the insets with respect to safe area, right? So it has four possible values. You can say never. So in this case, the system will never do anything for you then you're on your own. So in this case, you don't see any insets. Then you can say scrollable indexes. So in this case, this scrollable is vertically scrollable because it's content-sized, it's greater than its frame, right? So, and of course sometimes if you say, if you make this scrollable vertically scrollable, always vertically scrollable, then it's also going to have an inset in the scrollable index, excuse me, right? So you can also say always. So no matter what your condition is, no matter what content you have, the system always add the safe area insets for you. And there comes this slightly interesting one which is called automatic. So how is it automatically done? Okay, firstly it's designed more for compatibility or backward compatibility. And most of the case is the same as scrollable access but identical to always for some conditions. For example, if the legacy property is enabled, right? The deprecated property is enabled, then it's going to be always. And if your scrollable horizontal axis is scrollable and has non-zero safe areas, and of course if your real controller is a child of navigation or tag controller, tag bar controller. And this is inferred from Apple's documentation. So if you want more insights, you can check this, right? So this automatic behavior sadly have some side effects or rather have some additional animation effects. For example, so this is our app, so the settings page. So, okay, this is start. Yeah, so the moment you push a new root controller with a scroll view and if your behavior is set to automatic, then you'll notice that the scroll view will somehow have an additional insight. As the animation goes, the scroll view is scrolling up to cancel the additional insight. See, as the animation goes, my scroll view is pushing out, being pushed up, right? So, I mean, this shouldn't, I mean, this may not be a side effect. You may want it, right? So just go ahead and talk to your designer to see whether you want to do this behavior. But if you don't, so you can just cancel it by setting this property. Setting this property in this instance, you can just say your scroll view about appearance that contain adjustment behavior equals to never, right? So all your scroll views will be excluded from this behavior. And, but bear in mind that there's also a side effect whereby system pages will be affected. For example, you may have image speaker, the system implemented image speaker, and you may use the view controller for sending emails, right? So all of those will be affected. So if you've been using this, then you cannot set the universal, the shared appearance because everything will be affected. And then you have totally no control and you have totally no access to the system's scroll view, right? So another way to solve the problem is but just use, just set this property properly, every instance before it's presented, right? So that way you can just save the system menu, save the system UIS from being affected. And also this new property is introduced which is called adjusted content insights. So how does this work? So this is a new property and actually let's do an experiment on how this works. So let's say we have a scroll view, right? At the bottom it has tag bar and at the top it has a variation bar, quite standard system UIS. Then let's print out the values. So I always tell them if I print out the content insight, then that's the correct value, right? You have top 64, bottom 49, which is added by the system, which is correct. And by now LS11, we realize they're all zero. And but the adjusted content insight is the correct value. So yeah, so that means the system after it has automatically adjusted, it changed this property so that we can read. And let's add a 10 point to all the content insight, top, bottom, left, and right. So what's the result? LS10 is look as expected. But on LS11, the content insight is the one you set just now. And the adjusted content insight will be this, right? So this is some new behavior. So that means the actual screw viewer LS11 is the adjusted content insight. So you might not, you shouldn't access the content insight to derive, to retrieve the correct value. But the problem comes where you want, you need to be backward compatible. That means you need to add, maybe some of your logic is reading this property and you need to handle it properly. So how can you do that? So one way to do that is you can just use a version check. And you can say if it's LS10, you can do something, if LS11, you can do something. And that's most of the case. That's how you resolve the compatibility issue in most of the cases. But in this case, you can do something else, which is this. So you can just turn off the adjustment behavior and LS11 so that you can safely access the content insight without any further issues. That is when you don't want to automatically adjustment. Another thing that we notice is that the screw viewer standard method, screw viewer big throw will be caught if you change the frame of a screw viewer. So you should pay special attention to this if you have any logics relying on each other. So for example, if your screw viewer big throw, sorry, if your frame change, maybe you want to do something that will trigger. Okay, so maybe let me put it this way. In the screw viewer big throw, then you trigger something that changes the frame. And when the frame is changed, that is caught again. So you might end up in that one in this way. So just be careful with this. And okay, so let's talk about how the variable works with table view. So actually months before iPhone 10 releases. So there's some smart guy came up with some really creative solutions. So one guy is the lady to solve the problem, right? So should the UI table view behave like this on iPhone 10? And how about the scroll indicators? You know the tiny little fire on the right indicating your scroll offset. So should it look like this, right? There's some bad apparently I found a solution, right? So the question is can we do this or should we do this, right? So it turns out that what we need to do is nothing. Okay, so actually if you don't do anything, the table view will behave totally respecting the safe areas. So in this case, this particular table view is attached to the far edges of the screen and we didn't do anything. So the header has a red, the header content view has a red background color. And the cell background view has a white background color. So judging from the color's distribution, then you realize that the content view of the cells as well as the header are automatically inset from the edge of the screen using the safe area, right? So that is because, right? So then you'll also notice that the background, the background color is not extended to the edge of the screen, right? So it changes together with your content view. That's just because the content view is inset. So if you want the colors to extend all the way edge to edge, then you should set the background view's background color, right? So it turns out that your table view has this new properties called inset content view to the safe area and by default it's turned on. That is why we didn't do anything and we saw the picture just now. So if you turn it off, then you'll see something like this. So as if there's probably no insets at all, right? So that's the case of table view. Then another behavior change that we realized is the estimated has default value have changed. So table views have a few estimated height, namely estimated raw height, estimated section foot height and estimated section header height. So previously, before iOS 11, their default value is disabled, right? So if you don't set this, then it's disabled. So starting with iOS 11, these values by default is automatic if you don't do anything. What does automatic mean? That means the height of the view is automatically measured by the system. All you need to do is you provide enough information for the system to calculate your views height. That's all you do. But the drawback of this or a side effect is that the reload of your table views, if you set the automatic, the reload is not going to be synchronized. Rather, it's going to be quite asynchronous. And you have no idea when the reloading of a table view is done. The system is doing a few rounds of layouts and measurements under the hood in the background. So if you have the code of these two lines, for example, I want my table view to reload data. And then at the next line, I want my table view to scroll to the bottom. Then you might be in trouble because the moment your second line is triggered, the moment you want to scroll to the very bottom, your table view may not be there. The reload may not finish at all. So one use case of this is in the case of a chat page, for example. Every time the user send a new message, so I insert one row in the table view, which is the list of the messages. And after I insert a message, I immediately want to scroll to the bottom because I want the user to see the latest information. So if I turn the estimates, if I don't do anything to the estimates, then it might fail due to the automatic behavior. So the way we solve the problem is the three lines above. And it turns out that you don't need to do any version checking. So on the previous iOS version, I was 10 and below, you set to zero to disable the automatic estimates. And on iOS 11, you set to zero also to disable it. But the problem is you need to set it explicitly like this. So if you have any logics relying on the immediate completion of the reloading of table view, then you need to take extra care of this. So how about collection view? It turns out collection view is quite similar to table view except the fact that it doesn't respect to save area by default. And there's little you can do. So the only way to make your collection itself respect to save area is to manually do it from the self level or from your reusable headers level. Just make sure they respect the save area of their super view. And on the collection view, there is a new property in the flow layout class which is called section inside reference. So the section can be referenced from content inside save area or layout margins. So some quick example. So this is when the reference is referencing from content inside of the entire view. And this is from the save area. And this is from the layout margins of the views, right? So this is the behavior of the collection view, right? So that's roughly about it. And some final notes. So first thing, do not assume those behaviors. Do not assume or rely on hard code methods only use them for debugging purposes. And also all the solutions we have seen just now is case by case and may or may not be applicable to your application. So just be careful of the side effects if you want to apply to any, right? Then third thing is some of those findings are based on experiments and which is keep improving, keep iterating. And also some of the APIs and system behaviors will improve. So maybe tomorrow there will be some better solutions on more evident ones. So that's why we need to stay connected and stay updated and share and learn from the community, right? And speaking of stay connected, our company is still hiring. So if you are interested in what we are building, what we are doing and how we do our job and feel free to talk with us. So I'm with the iOS team and our team is over there. So just a little wave, guys. Right, so if you want to know about it, so welcome to talk to us or talk to our HR aura over there. Yep, so, and also check out these references. So I referred some ideas from these articles. They are quite some good news. And this, and yeah, so any questions? Any questions about the topics about any other questions in general? Okay, I just want to ask for any, for your own internet apps like Shopee and all this, do you all have, you know, like a really go-to adversary and decided I should move this, I just said, or is there some thing that you all did such that it works well in both cases? Well, like I mentioned just now, right? So if you aren't using auto layout, if you are using the systems controls, for example, the systems navigation bar or tool bar, then you are in good shape. You don't need to do anything special, right? And the thing is, you need to pay special attention for the customized views, the views that you use, calculation, manual layout, right? So, and of course, the views that have a lot of the interactions may have changed, right? Because the JSON net recognizers may change according to how the views are laid out. So, yeah, so when we are adapting our app to iPhone 10, we basically went through all the pages to verify that all of them are able to produce a correct layout for our user to use, and we are just according to them. So question regarding a specific position. I was wondering if you guys had any trouble with the new UI search bar with respect to the new science, what I've noticed is especially when you try to add it to like navigation controllers or something like that, sometimes it will just not show up or things like, it won't show up in a bar, but I think it looks like that. So, I'm just wondering. So, we do notice some abnormal behavior with the search bar. So, I think one part of this is because all the navigation items are now using auto layout, right? So, internally, actually it's using auto layout to lay out all the bar bar items and search bars and whatever. So, actual suggestion of this is if we want to put manual or custom views on the navigation bar, we should provide sufficient information of the sizing. That means within your custom view on the navigation bar, you should attach your views. Your views should be well-defined in terms of width and height. And the edges of the view should attach to your subview or container views edges so that when the navigation bar lay out your views, it can be layout property. So, that's Apple's suggestion. And we actually do some inspection of the navigation bar. Then we realize that actually, yes, indeed it's using auto layout. And some of the navigation items, sorry, the bar button items is actually using stack view. So, they are basically stacking each other side by side, something like that. So, one way to fix the layout issue was to change the properties of the stack views. But, those are internal APIs and we shouldn't assume that the stack views is the solution in the future, right? So, Apple can basically internally change the implementation. So, we should never do this. This is only for exploration. So, the way we solved the search bar is we, so one way we did was we used a UI search bar, sorry, UI search controller. So, we don't manually stack the title view of the navigation bar to my search bar. Instead, we create this UI search controller and then we just set it to the navigation item. If I remember correctly, yes. So, then the layout issues can be solved, yeah. And instead of doing this, we also did one more exploration which also worked is, so, because Apple suggested us to provide sizing information. So, we noticed the navigation, sorry, we noticed the search bar size is incorrect. So, we actually collected sizing information. We changed the intrinsic content size. So, that would be used in the auto layout and that also did work. But, that, I don't think is a suggested solution. The correct, I mean, the recommended they should use UI search controller. Yes. And. Thank you. Thank you. They need to use the mic. They need to use the mic. Everyone, thank you. Hi, so I'm just wondering, like, is it possible? I mean, you mentioned there's like a safe area in the content area. Yes, yes. So, let's say my navigation bar is correct, then my tab bar is white. Yes. How do I, like, is it possible to have different colors for this non-safe area? Like, for the status bar and the home indicator as well? Yes. So, actually, you can adjust the background color of the navigation bar and tab bar. So, it's actually customizable and they have the APIs for you to do your configuration. Also, they're separate. Because I'm just placing it on the slides that you've been showing. You mean the top and bottom are separate? Yes, they are separate. Okay. They're independent of each other. Yeah. No questions. And I just wanted to ask you a question regarding the search bar. One, another thing we do is we just implement the navigation bar ourselves. Don't use the Apple navigation bar. I don't know. So, we just implemented ourselves as DIY. That usually all works. If you have your own custom transitions, if you have your own fancy tool animations, then you can implement those on your own versions. But, just in case, in the future, Apple has introduced a bigger notch on the top. Then you adjust. Then you need to do for the adjustment. But, if you are just using a system one, then you should be in good shape. If you are respecting this area. And with the introduction of iOS 11, we have a few new behaviors on the UI navigation controller. So, we have the large titles, right? So, you can turn that on by just assigning a single boot property so that you have the bigger titles. And as you scroll, the bigger title can be streamed to the normal title. And it's quite a good behavior. I mean, it's quite a good experience. And you can talk to your designers to see how they can adapt to this new design. There's no normal questions. No worries. We'll approach us later on. With that, thank you for listening. Let's give this a round of applause.