I want to my interface look the same on iPhone and iPad. Like on my images:
And I use UICollectionCompostionLayout
and this code to do it:
func carouselSection(using section: Section) -> NSCollectionLayoutSection {
let itemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .fractionalHeight(1.0))
let layoutItem = NSCollectionLayoutItem(layoutSize: itemSize)
var layoutGroupSize = NSCollectionLayoutSize(widthDimension: .absolute(0), heightDimension: .absolute(0))
var layoutGroup = NSCollectionLayoutGroup.horizontal(layoutSize: layoutGroupSize, subitems: [layoutItem])
switch UIDevice.current.userInterfaceIdiom {
case .phone:
let a:CGFloat = UIScreen.main.bounds.size.height/8
let b:CGFloat = UIScreen.main.bounds.size.height
layoutGroupSize = NSCollectionLayoutSize(widthDimension: .absolute(b - (a) ), heightDimension: .absolute(b))
layoutGroup = NSCollectionLayoutGroup.horizontal(layoutSize: layoutGroupSize, subitems: [layoutItem])
layoutGroup.contentInsets = NSDirectionalEdgeInsets(top: a, leading: a/2, bottom: a, trailing: a/2)
case .pad:
let a:CGFloat = UIScreen.main.bounds.size.height*0.25
let h:CGFloat = a * 1.8
let b:CGFloat = UIScreen.main.bounds.size.height
layoutGroupSize = NSCollectionLayoutSize(widthDimension: .absolute(b - (h)), heightDimension: .absolute(b - (a)))
layoutGroup = NSCollectionLayoutGroup.horizontal(layoutSize: layoutGroupSize, subitems: [layoutItem])
layoutGroup.contentInsets = NSDirectionalEdgeInsets(top: a, leading: a/10, bottom: 0, trailing: a/10)
default:
print(UIScreen.main.bounds.size.height)
}
let layoutSection = NSCollectionLayoutSection(group: layoutGroup)
layoutSection.orthogonalScrollingBehavior = .groupPagingCentered
layoutSection.visibleItemsInvalidationHandler = { (items, offset, environment) in
items.forEach { item in
let distanceFromCenter = abs((item.frame.midX - offset.x) - environment.container.contentSize.width / 2.0)
let minScale: CGFloat = 0.7
let maxScale: CGFloat = 1.1
let scale = max(maxScale - (distanceFromCenter / environment.container.contentSize.width), minScale)
item.transform = CGAffineTransform(scaleX: scale, y: scale)
}
}
return layoutSection
}
I get approximately the same result as I want. But I’m worried about my code. I do too many weird calculations to make my interface look the same on iPhone and iPad.
like this for iPhone:
let a:CGFloat = UIScreen.main.bounds.size.height/8
let b:CGFloat = UIScreen.main.bounds.size.height
like this on iPad:
let a:CGFloat = UIScreen.main.bounds.size.height*0.25
let h:CGFloat = a * 1.8
let b:CGFloat = UIScreen.main.bounds.size.height
Also I do different calculations for iPhone and iPad although UICollectionCompostionLayout
was created specifically to do a minimum of calculations but the interfaces looked the same on different devices. What should I fix in my code?
2
Answers
I think I got a solution which removes the funky calculations:
My main idea was to take
contentSize.width
as a reference point, to calculate thegroupWidth
for 3 equally sized boxes,We can then set the group size to this absolute value and calculate the section offset to center the groups vertically:
The final piece is to set
section.interGroupSpacing
to something larger thaninterGroupSpacing
likeinterGroupSpacing * 1.5
to push the left and right group out of the container.I also had to adjust your scaling code slightly and add
section.contentInsetsReference = .none
because there were some issues on iPhone with elements appearing behind the notch.Result on iPhone 15
Result on iPad 10th gen
This is not direct answer for your question but a guide for UI how you can handle
Below is what I use for sizing & even fonts. I use it everywhere…
Note, always depend on
width
as height can be different.Above 428 is nothing but the designer width of the screen (e.x for my portrait app, designer design width of screen as 428)
Now you will give sizes based on the design you get.
Let me explain with example.
In this UI I will explain with the
Send OTP
button. Code will be as below.OR you can do as per below image
And don’t forget to make your collection view center vertically
Now if you run app in iPhone OR iPad, you will see same UI.
Note : I am using Stevia library for UI purpose. Stevia & above
iPhoneFactorX
make great (pixel perfect) UI…