- Compositional Layout в iOS 13. Основы
- Введение
- Compositional Layout
- List Layout
- Grid Layout
- Two Column Layout
- Inset Items Grid Layout
- Distinct Sections Layout
- Adaptive Sections Layout
- Nested Groups
- Nested Groups Scrolling
- Заключение
- Layout from Instagram 4+
- Instagram, Inc.
- iPhone Screenshots
- Description
- What’s New
- Ratings and Reviews
- Always come back 2 LAYOUT
- Faulty app?
- Needs a fix to let you start over
- App Privacy
- Data Linked to You
Compositional Layout в iOS 13. Основы
На практике iOS разработчик часто сталкивается с задачей показа большого количества информации в виде списка или в виде коллекции, как правило, для этого отлично подходят UITableView или UICollectionView . Также часто встречается задача реализации экрана, который представляет собой комбинацию списка и коллекции.
В данной статье рассмотрим, какие новые возможности принесла iOS 13 для реализации этой задачи.
Введение
Представьте вам пришла задача реализовать экран, на котором информация может скролится как и вертикально, так и горизонтально, каждая секция имеет свой лайаут, например как в приложении AppStore.
Как вы будете такое реализовывать?
До iOS 13, скорее всего вы бы это делали так
- Таблица, в каждой ячейке которой находится коллекция
- Коллекция, в каждой ячейке которой находится другая коллекция
- Коллекция, со своим кастомным лайаутом
- Свой кастомный наследник UIScrollView
Все эти решения содержат ряд проблем.
- Это сложно реализовывать и поддерживать
- Сложно добиться хорошей производительности
- Сложно сделать анимацию
- Сложно сделать поддержку self-sizing ячеек
- Сложно сделать одновременную поддержку iPad и iPhone
- Решение заточено только на определенный сценарий
Разработчики крутились как могли и так было вплоть до iOS 12.
Compositional Layout
В iOS 13 Apple представила нам новый способ построения лайаута коллекции, он призван сильно упростить реализацию таких экранов — Compositional Layout, этот подход основан на 3-х принципах — компоновка, гибкость и скорость.
Начнем с первого принципа — компоновка, он означает построение сложных вещей из более простых, гибкость означает, что мы можем построить лайаут почти любой сложности, адаптировать его к любому экрану и скорость, все это работает очень быстро, вам не нужно думать о производительности, фреймворк сделает это за вас.
Compositional Layout — использует декларативный подход, это значит он описывает как должен выглядеть лайаут, а не говорит как его сделать.
Основные концепты так же включают в себя
- Композиция маленьких смежных групп вместе
- Смежные группы располагаются по линиям
- Использование композиции вместо наследования
Композиция маленьких смежных групп вместе — означает, что мы берем отдельные элементы и комбинируем их в группы, далее мы можем комбинировать получившиеся группы каким-то другим способом и получать уже новую группу. Таким образом мы строим наш лайаут, комбинируя его из разных групп элементов.
Смежные группы располагаются по линиям — принцип grid-лайаута, как стандартный flow-лайаут располагается по линиям, так и группы располагаются по линиям.
Использование композиции вместо наследования — наследование обладает некоторыми недостатками, поэтому лучше создать отдельный объект, сконфигурировать и использовать его.
Давайте рассмотрим основные классы Compositional Layout. Для построения лайаута нам понадобятся эти 4 класса:
- NSCollectionLayoutSize — определяет размер элемента;
- NSCollectionLayoutItem — определяет элемент лайаута;
- NSCollectionLayoutGroup — определяет группу элементов лайаута, сам по себе тоже является элементом лайута;
- NSCollectionLayoutSection — определяет секцию для конкретной группы элементов;
- UICollectionViewCompositionalLayout — определяет сам лайаут.
Посмотрим на определение UICollectionViewCompositionalLayout .
Как вы видите UICollectionViewCompositionalLayout является наследником UICollectionViewLayout , а значит может использоваться при создании UICollectionView .
List Layout
Давайте рассмотрим как это работает на практике. Для этого создадим новым storyboard-проект, с пустым UIViewController , в методе viewDidLoad() будем создавать UICollectionView программно и в init(frame:, layout:) передадим наш объект UICollectionViewCompositionalLayout . Весь код можно будет найти по ссылке в конце статьи, а сейчас сосредоточимся на самом создании UICollectionViewCompositionalLayout .
Для наглядности покажем, конфигурацию нашего лайаута. Справа покажем какого размера элементы лайаута, красный для ячейки, оранжевый для группы, желтый для секции.
И сам метод создания лайаута.
Объект itemSize определяет высоту и ширину элемента, в параметрах нужно указать размер для каждого измерения, за определение измерения отвечает класс NSCollectionLayoutDimension . Рассмотрим более подробно какие параметры мы можем указать.
- fractionalWidth(_:) , относительная величина, принимает значения от 0 до 1 включительно, определят ширину относительно ширины контейнера, 0.5 — ширина равна половине ширины группы (контейнера) элемента;
- fractionalHeight(_: ) , относительная величина, принимает значения от 0 до 1 включительно, определят высоту относительно высоты контейнера, 0.5 — высота равна половине высоты группы (контейнера) элемента;
- absolute(_: ) , абсолютная величина, указывает точный размер, например 44.0 ;
- estimated(_:) , приблизительная величина, точный размер будет известен на этапе рендеринга.
В нашем случае itemSize имеет размеры widthDimension = .fractionalWidth(1.0) , heightDimension = .fractionalHeight(1.0) , что означает что его высота и ширина равна высоте и ширине группы, которая содержит этот элемент. После этого мы можем создать сам элемент и передать ему созданный размер.
Далее аналогичным образом мы задаем размер для группы, widthDimension: .fractionalWidth(1.0), heightDimension: .absolute(44) , означает что ширина группы будет равна ширине секции, которая содержит эту группу, а высота будет иметь абсолютное значение 44.0 .
Саму группу можно создать разными способами:
- horizontal(layoutSize: , subitem: , count: ) , определяет группу, которая будет иметь определенное количество элементов равного размера расположенных горизонтально;
- horizontal(layoutSize:, subitems: ) , определяет группу, которая будет повторять элементы до тех пор, пока не закончится место по горизонтали;
- vertical(layoutSize:, subitem:, count:) , определяет группу, которая будет иметь определенное количество элементов равного размера расположенных вертикально;
- vertical(layoutSize:, subitems: ) , определяет группу, которая будет повторять элементы до тех пор, пока не закончится место по вертикали;
- custom(layoutSize:, itemProvider: ) , определяет кастомную группу, где клиент указывает расположение элементов сам.
Как возможно вы подметили, .horizontal и .vertical методы располагают элементы, как в обычном стеке, горизонтально и вертикально соответсвенно, .custom позволяет указывать расположение элементов самому, например можно написать логику, чтобы элементы располагались по диагонали.
Наш способ создания группы NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitems: [item]) говорит о том, что элементы заполняются в горизонтальном порядке и до тех пор, пока есть место.
Далее мы создаем секцию NSCollectionLayoutSection(group: group), которая будет содержать нашу созданную группу. И эту секцию мы будем использовать для создания нашего Compositional Layout .
Выглядит неплохо, но сейчас это больше похоже на таблицу, чем на коллекцию. Как мы можем это изменить?
Grid Layout
И так, как нам добиться такого результата? Есть несколько способов это сделать, один из них это просто задать новый размер элемента в группе, чтобы элемент занимал не всю группу по ширине, а только ее четверть.
Получилось, теперь у нас всегда будет 4 колонки в независимости от девайса, его размера и его ориентации.
Two Column Layout
Есть другой способ, как можно установить количество колонок в коллекции, его можно задать явно при создании группы, тогда группа сама посчитает какой ширины должны быть ее элементы, чтобы удовлетворять условию, в этом случаем widthDimension элемента игнорируется.
Как это описывается в коде.
Так же мы добавили отступы между элементами в группе group.interItemSpacing = .fixed(spacing) , отступы между группами в секции section.interGroupSpacing = spacing , а так же установили contentInset у секции section.contentInsets = .init(top: spacing, leading: spacing, bottom: spacing, trailing: spacing) . Таким образом ячейка со всех сторон имеет отступ равый spacing .
Как вы могли заметить, расстояние между элементами в группе interItemSpacing задается не с помощью скалярной величины, как расстояние между группами в секции interGroupSpacing , а как объект класса NSCollectionLayoutSpacing .
- func fixed(_ fixedSpacing: ) , задает фиксированое расстояние между элементами;
- func flexible(_ flexibleSpacing:) , задает не строгое расстояние между элементами, часто используется для того, чтобы заполнять свободное пространство в группе;
Inset Items Grid Layout
Как добиться того, чтобы ячейки были квадратными, а не прямоугольными? Как мы знаем, у квадрата ширина и высота равны, сделаем это методом указания относительных величин. Например, мы хотим иметь 5 колонок, поэтому можем указать, чтобы ширина элемента была равна 1.0/5.0 от ширины группы, а высота была равна высоте группы. Для группы же укажем чтобы она имела ширину секции, а высоту равную 1.0/5.0 ширины секции. Так как ширина группы совпадает с шириной секции, получим элементы с равной шириной и высотой.
Так же покажем, что можно задавать .contentInsets и у NSCollectionLayoutItem .
Как это описывается в коде.
Distinct Sections Layout
До сих пор мы рассматривали один лайаут для одной секции, но у нас есть так же возможность указать различные лайауты для различных секций.
Еще раз взглянем на определение класса UICollectionViewCompositionalLayout и заметим, что мы можем создать лайаут с помощью заданного нами блока UICollectionViewCompositionalLayoutSectionProvider .
UICollectionViewCompositionalLayoutSectionProvider принимает 2 параметра, первый это номер секции, второй окружение, возвращает же блок лайаут для данной секции.
Давайте определим 3 секции, для первой секции определим лайаут в виде списка, для второй в виде grid-лайаута с 3-я колонками, для третьей так же в виде grid-лайаута, но с 5-ю колонками.
Как это описывается в коде.
Adaptive Sections Layout
Если нам нужно сделать лайаут более адаптивным для секции, то для этих целях нам поможет NSCollectionLayoutEnvironment класс, он предоставляет размер контейнера и traitCollection .
Если приложение запускается в сompact size-class по вертикали, как в лэндскейп ориентации айфона, то мы ходтим адаптировать лайаут таким образом, чтобы проставлялась фиксированная высота, дабы контент помещался на экране.
Мы можем проверять traitCollection.verticalSizeClass у layoutEnvironment и проставлять нужную высоту для группы.
Так же мы можем смотреть ширину в container.effectiveContentSize у layoutEnvironment и проставлять нужное количество колонок для секции.
А вот так это будет выглядеть в лэндскейп ориентации.
Как это описывается в коде.
Nested Groups
Если взглянуть на определение класса NSCollectionLayoutGroup , то можно увидеть, что он наследник класса NSCollectionLayoutItem , а значит может быть, использован как элемент в другой группе, тем самым у нас есть возможность создавать вложенные группы.
Как это описывается в коде.
Nested Groups Scrolling
Как на счет горизонтального скрола? Легко! Для этого, всего лишь на всего, нужно проставить соответствующее значение у секции.
Заключение
iOS 13 принесла новый способ создания лайаута для UICollectionView , с помощью Compositional Layout можно легко и быстро создавать экраны почти любой сложности.
В данной статье были рассмотрены основные классы и их взаимодействие с друг другом. В следующей статье рассмотрим более продвинутые техники создания лайаута.
Источник
Layout from Instagram 4+
Instagram, Inc.
-
- #42 in Photo & Video
-
- 4.4 • 87.6K Ratings
-
- Free
iPhone Screenshots
Description
Create fun, one-of-a-kind layouts by remixing your own photos and sharing them with your friends.
Choose photos from your camera roll—or use the built-in Photo Booth to take spur-of-the-moment shots—and instantly see them laid out in various combinations. Pick the layout you like best, then edit it to make it your own.
Layout’s smooth, intuitive process gives you complete creative control. Tap to mirror, flip or replace images, hold and drag to swap them, pinch to zoom in or out, or pull the handles to resize. You’re the editor, so get creative—tell a story, show off an outfit or just splice, dice and change the look of your regular photos to convey a mood or theme.
* Re-mix up to 9 of your photos at a time to create fun, personalized layouts.
* Use the Faces tab to quickly find photos with people in them.
* Capture the moment in Photo Booth mode with quick, spontaneous shots.
* Save your layouts to your camera roll and share them seamlessly to Instagram or other networks.
* Easily see the last 30 photos you’ve selected in the Recents tab.
* Pair your layouts with Instagram’s filters and creative tools afterwards to make them stand out even more.
* Download and start creating immediately. No signup or account required—and no clutter breaking up your flow.
What’s New
This app has been updated by Apple to display the Apple Watch app icon.
Bug fixes and performance improvements.
Ratings and Reviews
Always come back 2 LAYOUT
I downloaded Layout very soon after installing INSTAGRAM. I’ve always been satisfied, too! The only addition I’d like is the ability to choose a border clr: Black,White, & Grey would be great! I’ve added approx 3 other collage makers over the last few yrs., & while I might use them a time or two, I always delete them in favor of Layout. I might find a different look, but the APPS lack simplicity, & real choices. They show tons of avail. layouts or backgrounds, but it’s quickly made obvious that u must PURCHASE a yearly sub. to use the app. They should advertise “ForeverFree Trial” bc that’s all you get to do. Nope! Layout is the only collage maker I can’t live without. It’s EZ, it’s full of options, and I’ve never had issues w/glitches! Thanks Layout!
Faulty app?
I loved this app, and I’ve had it forever. I had it on my iphone xs and now my iphone 12 mini BUT for as long as ive had it, my instagram kept crashing, overheating my phone, and draining my battery. As well as i kept getting hacked or having random logins from other countries (mainly russia).
I thought the problem would resolve once i bought a new phone, but it followed me. I couldn’t be on the instagram app for longer than 30 seconds before it crashed. Then today, i was using this layout app to edit something and the layout app CRASHED. it did it several times before it occurred to me that this is the problem.
So I deleted this app, deleted my instagram app, restarted my phone and then re-downloaded instagram (but not this layout app) and now the problem is 100% gone. No more overheating, no more battery drains, no more crashing instagram. Im literally shocked that it took me years to figure this out. Disappointed because the app did what i needed it to, but in the process was disrupting my instagram app.
Needs a fix to let you start over
Let me just say that I have used this all the time, and would give it 5 stars, until an update that broke something.
So one of the more recent updates, not sure which one, made it so that you can’t get back to the starting screen. You have to close the app.
It added extra steps into selecting photos and making your layout. And I’m not really sure why? From a user experience perspective, it makes zero sense— Because not only does it add the extra steps, but there’s no way to clear the selection and start over. You can’t access your photo roll, if you click on recents it only has the things you recently selected. Which I find to be completely unuseful.
It’s the GUI equivalent of a keyboard trap. I was hoping that maybe the logo or something else would let me clear the selection and access my photo roll once more. But there doesn’t appear to be any way to do this. I am super bummed that I have to close the app every time just to get a pop-up to ask if I want to clear my selection and use different photos.
If something was done to address this, I would totally give this 6 stars! I use this app all the time and I’m really disappointed that the functionality has been crippled in this way.
(The reason I’m not sure which update caused this change is because I hadn’t installed any of the updates for a while. But had to recently when I upgraded my phone.)
App Privacy
The developer, Instagram, Inc. , indicated that the app’s privacy practices may include handling of data as described below. For more information, see the developer’s privacy policy.
Data Linked to You
The following data may be collected and linked to your identity:
Источник