Size classes on Modal Views - iphone

I am trying to set different constraints for iPad and iPhone (4'').
I have set Regular Height and Compact width constraints for iPhone. But these constraints are shown on 7.9'' iPad, 9.7'' iPad.
These constraints are for a modal view.
How do i make my Regular Height and Compact width constraints limit to my iPhones only.

Because the form sheet presentation on iPad is compact width and regular height, It is taking those constraints.
Formsheet ios 8 constraints are same as iphones constraints
The solution is to override traitCollection in the Presented view controller
override var traitCollection: UITraitCollection
{
if UIDevice.isIPad()
{
let traits = UITraitCollection(horizontalSizeClass: UIUserInterfaceSizeClass.Regular)
let traits2 = UITraitCollection(verticalSizeClass: UIUserInterfaceSizeClass.Regular)
let traitCollection = UITraitCollection(traitsFromCollections: [traits, traits2])
return traitCollection
}
else
{
return super.traitCollection
}
}

As a note, iOS Docs have this warning for traitCollection:
Use the traitCollection property directly. Do not override it. Do not provide a custom implementation.
With that known, here's an Obj-C solution which combines super traits w/ updated horizontal/vertical traits:
- (UITraitCollection *)traitCollection {
UITraitCollection *traitCollection = [super traitCollection];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
UITraitCollection *horizontalTraitCollection = [UITraitCollection traitCollectionWithHorizontalSizeClass:UIUserInterfaceSizeClassRegular];
UITraitCollection *verticalTraitCollection = [UITraitCollection traitCollectionWithVerticalSizeClass:UIUserInterfaceSizeClassRegular];
traitCollection = [UITraitCollection traitCollectionWithTraitsFromCollections:#[traitCollection, horizontalTraitCollection, verticalTraitCollection]];
}
return traitCollection;
}

Related

How to change the size of modal or sheet in SwiftUI?

How to change the size of modal or sheet in SwiftUI? Just like the ones in the pictures. I noticed that the AirDrop options appear as a full-screen sheet on iPhones but on iPads that is not the case (as you can see).
I'm creating an app with a login form, this size personalization would be useful to optimize the size of the device because most of the space isn't used.
Is there a way to change the size of those components?
From your description, I didn't really understand what do you want to achieve, but this enum will help you to determine what device is currently running. You can build a logic of what do you want to present around a simple if else statement:
if DeviceTypes.isiPad {
// logic for all iPads
} else {
// logic for other devices
}
And here is Enum:
enum DeviceTypes {
enum ScreenSize {
static let width = UIScreen.main.bounds.size.width
static let height = UIScreen.main.bounds.size.height
static let maxLength = max(ScreenSize.width, ScreenSize.height)
}
static let idiom = UIDevice.current.userInterfaceIdiom
static let isiPad = idiom == .pad && ScreenSize.maxLength >= 1024.0
}

How to change design according to screen size using NSLayoutConstraint in swift

I have designed a screen using Storyboard constraints for iPhone XR, but that design become big in iPhone7, so I want to change the height and width of my ContainerView using NSLayoutConstraints.
I have taken:
#IBOutlet weak var containerViewheight: NSLayoutConstraint!
This ContainerView actual height in iPhoneXR is 300, so I want to change it in iPhone7
For example:
if (iphone7) {
self.containerViewheight.constant = 240
}
if (iphone SE) {
self.containerViewheight.constant = 280
}
Unfortunately I have very little knowledge in size classes.
You can always ask the UIScreen class method main for the current concrete size, it returns the concrete size of the current device.
let deviceSize = UIScreen.main.bounds.size
But you probably know, that height and width change depending on the orientation the device has (landscape or portrait).
Maybe this extension could help:
import UIKit
extension UIScreen {
/// Retrieve the (small) width from portrait mode
static var portraitWidth : CGFloat { return min(UIScreen.main.bounds.width, UIScreen.main.bounds.size.height) }
/// Retrieve the (big) height from portrait mode
static var portraitHeight : CGFloat { return max(UIScreen.main.bounds.size.width, UIScreen.main.bounds.size.height) }
/// Retrieve the (big) width from landscape mode
static var landscapeWidth : CGFloat { return max(UIScreen.main.bounds.size.width, UIScreen.main.bounds.size.height) }
/// Retrieve the (small) height from landscape mode
static var landscapeHeight : CGFloat { return min(UIScreen.main.bounds.size.width, UIScreen.main.bounds.size.height) }
}
You can manipulate by knowing what ratio you want your container height to be of the screen height.
For eg: if UIScreen.main.bounds.height gives you 1000. And your appropriate container height here is 400. Then the required ratio of height of container to height of screen is 400/1000 or 2/5.
Now, what you can do is write
containerViewheight.constant = (2/5)*UIScreen.main.bounds.height

How to increase size of UICollectionView on Scroll

I want to increase the size of collectionView on Scroll. It's called Parallax affect.
I have 3 classes with named
1)class PhotoGalleryViewController' with storyboard.
PhotoGalleryViewController contains collectionView and a cell with imageview.
2) class ListingDetailContentViewController' without storyboard
3) class ListingDetailViewController' with storyboard.
ListingDetailViewController is appending ListingDetailContentViewController as child.
contentViewController = ListingDetailContentViewController(hideComparable: comparableIsHidden)
contentViewController.view.translatesAutoresizingMaskIntoConstraints = false
contentViewController.listingDetailViewController = self
addChild(contentViewController)
view.addSubview(contentViewController.view)
view.sendSubviewToBack(contentViewController.view)
ListingDetailContentViewController is appending photoGalleryViewController using Library AloeStackViewController. AloeStackViewController is UIScrollView so thats why i made its delegate in ListingDetailContentViewController
class ListingDetailContentViewController: AloeStackViewController, PhotoGalleryViewControllerDelegate, UIScrollViewDelegate {
// MARK: - Private functions
private func setupView(ad: Ad) {
// Display photos
if let photos = ad.photos {
photoGalleryViewController = UIStoryboard(name: "Listing", bundle: nil).instantiateViewController(withIdentifier: "PhotoGalleryViewController") as? PhotoGalleryViewController
let photoView = photoGalleryViewController.view!
stackView.addRow(photoView)
stackView.setInset(forRow: photoView, inset: .zero)
photoGalleryViewController.photos = photos
photoGalleryViewController.ad = ad
photoGalleryViewController.delegate = self
actualFrame = photoGalleryViewController.collectionView.frame.height
}
// Some other stuff
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// The link i applied here is https://stackoverflow.com/questions/33481928/imageview-scaling-when-scrolling-down
let offsetY = scrollView.contentOffset.y
if offsetY < 0 {
photoGalleryViewController.collectionView.frame.size.height += actualFrame - offsetY
photoGalleryViewController.view.frame.size.height += actualFrame - offsetY
self.loadViewIfNeeded()
} else {
photoGalleryViewController.collectionView.frame.size.height = actualFrame
photoGalleryViewController.view.frame.size.height = actualFrame
self.loadViewIfNeeded()
}
}
}
I tried this help but not worked for me.
My image is at top of screen. and other things are below.
When ever user scrolls down. Image should be increase.
Kindly help me out to solve this problem.
Update:
Answer:
I have done it with help of library called ParallaxHeader. I simply add this library using Pod and follow the tutorial given in library.
After a lot of struggle I achieved my goal that were asked in Question.
I have done it with help of library called ParallaxHeader.
I simply add this library using Pod and follow the tutorial given in library.

How to to determinate in Swift the current width of the app when in Split View?

EDIT: I have a project with a row of buttons on top on it. Usually the buttons are 5 in Compact view and 6 in Regular view. I would like to remove a button when the app runs in 1/3 Split View. How can I determine the width of the app?
I'm using this code to determinate the current width of the app when in Split View (multitasking):
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
// works but it's deprecated:
let currentWidth = UIScreen.mainScreen().applicationFrame.size.width
print(currentWidth)
}
It works, but unfortunately applicationFrame is deprecated in iOS 9, so I'm trying to replace it with this:
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
// gives you the width of the screen not the width of the app:
let currentWidth = UIScreen.mainScreen().bounds.size.width
print(currentWidth)
}
The problem is that the first statement gives you the effective width of the app and it's fine, instead the second one, gives you the width of the screen, so you can't use it to learn the real width of the app when it is in Split View.
Would someone know what code would be necessary to replace this deprecated statement?
let currentWidth = UIScreen.mainScreen().applicationFrame.size.width // deprecated
#TheValyreanGroup's answer will work if there are no intervening view controllers mucking with sizes. If that possibility exists you should be able to use self.view.window.frame.size.width
You can just get the size of the parent view.
let currentSize = self.view.bounds.width
That will return the width accurately even in split view.
You can do something like this to determine whether to show or hide a button.
let totalButtonWidth: Int
for b in self.collectionView.UIViews{
let totalButtonWidth += b.frame.width + 20 //Where '20' is the gap between your buttons
}
if (currentSize < totalButtonWidth){
self.collectionView.subviews[self.collectionView.subviews.count].removeFromSuperview()
}else{
self.collectionView.addSubview(buttonViewToAdd)
}
Something like that, but i think you can get the idea.
Thanks to the replay of TheValyreanGroup and David Berry on this page I made a solution that can respond to the interface changes without using the deprecate statement UIScreen.mainScreen().applicationFrame.size.width I post it here with its context to made more clear what is the problem and the (surely improvable) solution. Please post any suggestion and comment you think could improve the code.
// trigged when app opens and when other events occur
override func traitCollectionDidChange(previousTraitCollection: UITraitCollection?) {
let a = self.view.bounds.width
adaptInterface(Double(a))
}
// not trigged when app opens or opens in Split View, trigged when other changes occours
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
adaptInterface(Double(size.width))
}
func isHorizontalSizeClassCompact () -> Bool {
if (view.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClass.Compact) {
return true // Comapact
} else {
return false // Regular
}
}
func adaptInterface(currentWidth: Double) {
if isHorizontalSizeClassCompact() { // Compact
// do what you need to do when sizeclass is Compact
if currentWidth <= 375 {
// do what you need when the width is the one of iPhone 6 in portrait or the one of the Split View in 1/3 of the screen
} else {
// do what you need when the width is bigger than the one of iPhone 6 in portrait or the one of the Split View in 1/3 of the screen
}
} else { // Regular
// do what you need to do when sizeclass is Regular
}
}

monotouch rotate in landscapemode and portrait mode

i am new to iPad developer,
i have created two or three iPad application in objective c using Xcode 4.
but now i want to create iPad application using Monodeveloper tool in C# language...
in which, i want to shift my tableView in orientation,
i searched in google but i didn't got any syntax.
for detail see my screen shot...
in first image (portrait mode) my Table is at extremeLeft , in second image (landscape mode) i want my table to be at extreme right..
how should i do this ?
i created tableview programatically, here is the code snippet,
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
Gainer(); //method call
UITableView Table=new UITableView();
Table.Frame=new RectangleF(20,200,400,400);
Table.Source=new TableViewDataSource(TopGainer); //passing parameter to tableview datasource
this.View.AddSubview(Table);
}
public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation)
{
// Return true for supported orientations
return true;
}
Any help will be appreciated.
Thanks In Advance !!
You can override the WillRotate method and apply the exact position you want, in every case, based on the values that UIScreen.MainScreen provides. E.g.
public override void WillRotate (UIInterfaceOrientation toInterfaceOrientation, double duration)
{
switch (toInterfaceOrientation) {
case UIInterfaceOrientation.LandscapeLeft:
case UIInterfaceOrientation.LandscapeRight:
Table.Frame = new RectangleF (UIScreen.MainScreen.Bounds.Width - 20 - Table.Frame.Width, 200, 400, 400);
break;
case UIInterfaceOrientation.Portrait:
case UIInterfaceOrientation.PortraitUpsideDown:
Table.Frame = new RectangleF (20, 200, 400, 400);
break;
}
base.WillRotate (toInterfaceOrientation, duration);
}