Height issue in ios devices with Hybrid app - ios

I am using ionic for application.I have one ionic modal in my app.When i am setting height in px or percentage its coming correct for all android device but not for ios.If i use .platform-ios for height in CSS for ios devices its not coming same for all ios devices.
I have added vh for ios but still not same for all ios devices.What can i do can anyone suggest me.
css:-
.appModal
{
height:120px;
}
.platform-ios .appModal
{
height:40vh;
}
Thank you.

You may want to have a look at this link.
You can see that iOS 9.3 Safari and above support the Viewport Height and Width measurements vh and vw
Older iOS devices don't support these, see the known issues tab on that link for more information.
As a fallback you can use something like:
.class-name {
height: 300px;
height: 40vh;
}
Browsers that support vh will use specified 40vh but older browsers/devices will see theres an error and default back to the 300px height.
Please note: more widely supported css should appear first in your markup. Otherwise you won't be able to overwrite for the newer browser.

i have this issue too ;
the best solutions i found is to use javascript is supported every where ;)
code be something like this :
var heighDevice = window.screen.height;
var FirstELement = document.getElementById('MyAppModal');//MyAppModal id element
var heightElm = (heighDevice * 40) / 100; // 40 is height in vh
// add the height to the element
FirstELement.style["height"] = heightElm + "px";

Related

iOS: Pickers broken on iOS 16, working on 15

I am working on creating a remote control app on iOS that involves pickers. On the iPhone SE, 3rd gen (iOS 15.6.1) I have been developing on, the pickers are coming out exactly as I intend. However, when I run the app on a simulator for a 3rd gen (16.1.1) iPhone SE, the pickers height is way off. Through testflight, I had a coworker download the app. He confirmed that, on his hardware, the pickers looked off. Here is what the picker is coming out like:
And here is how it looks on my iphone, how I intend it to look:
(My apologies for the different image sizes)
These pickers start as uninitialized class variables. When initializing the pickers, I want their height and width to be equal to the view they are seated in. When debugging this issue, I added two lines. One prints out the height argument I feed the constructor, and the other prints out the size of the picker after being constructed.
print("pickerRect height argument: " + String(Int(pickerFrame.frame.height))) // reading out 80
rolloffPicker = UIPickerView(frame: CGRect(x: 0, y: 0, width: pickerFrame.frame.width, height: pickerFrame.frame.height))
print("picker height: " + String(Int(rolloffPicker.frame.height))) // reading out 162
Now here is whats baffling me... On the physical iPhone SE it prints out 80 on both lines. For whatever reason, in the sim, it prints out the argument as 80, and the initialized size as 162. I have also tried constructing the CGRect before passing it in, the CGRect readsout 80 after being constructed, but once fed into the picker the size shoots up to 162 again. I have not touched the rolloffPicker variable until this line, and don't have any autolayout going with the picker.
My Mac is on Ventura 13.0.1, XCode is on Version 14.1. The physical iPhone was on 15.6.1, and the sim is on 16.1.1. When I updated the physical iPhone to 16.1.2, the pickers broke! Clearly this issue is in relation to the new update? What changed, and how might I work around it?
Update: Can't believe I missed this, but I am getting this message in the console when constructing the picker:
2022-12-09 19:35:14.434387-0700 Remote Control[645:22988] -[UIPickerView setFrame:]: invalid size {107, 72} pinned to {107, 162}
Update 2:
I tried to add constraints to the picker:
rolloffPicker.translatesAutoresizingMaskIntoConstraints = true
rolloffPicker.widthAnchor.constraint(equalToConstant: pickerFrame.frame.width).isActive = true
rolloffPicker.heightAnchor.constraint(equalToConstant: pickerFrame.frame.height).isActive = true
Now I am getting warnings, pickers size is way off...
AHHHH I fixed it! I changed
rolloffPicker.translatesAutoresizingMaskIntoConstraints = true
to
rolloffPicker.translatesAutoresizingMaskIntoConstraints = false
while keeping the constraints. Why this broke between iOS 15 and 16 is an enigma to me, hopefully this can help someone else out in the future.

Ios webview with capacitor, set safe areas

Using capacitor to build an app in ios. In ios the webview covers the whole screen, for iphone-x that means the notch will be included and content will go behind it, like the picture on the right. But i want the picture on the left, black bars on 'no go areas'.
The expected solution (html/css) for this would be to set correct viewport and use the 'safe-area'insert-?', se: https://css-tricks.com/the-notch-and-css/
But for the webview in ios the 'safe-area'insert' will always be 0, that is how it works => this solution is useless.
How can i solve this? Can i change the webview to not cover the whole screen, without changing in the capacitor-framework?
You can use a compatible Cordova plugin cordova-plugin-safearea
npm i -D cordova-plugin-safearea
npx cap sync
With this installed, you can request the safe margin area over the cordova/capacitor bridge:
// Types for clarity
type SafeArea = {
top: string,
bottom: string,
}
window.plugins.safearea.get(
(result: SafeArea) => {
// elegantly set the result somewhere in app state
},
(error: any) => {
// maybe set some sensible fallbacks?
}
);
You could use these values to specify extra padding on the body, or on your header / bottom-menu components
The docs say it returns the values as Numbers, but it seems to me they are actually strings (consider parseFloat before doing math with them).
I have just implemented this in React (running the getter in React.useLayoutEffect); the project is wrapped in Capacitor and have tested on two iOS devices with different ingenious Apple notch screen formats (iPhone 8 and iPhone 11 Pro).
Refer to the documentation for more at https://github.com/rickgbw/cordova-plugin-safearea
There is a CSS variable preset by capacitor you can use to set the padding or a margin for example.
html {
--ion-safe-area-top: env(safe-area-inset-top);
--ion-safe-area-bottom: env(safe-area-inset-bottom);
--ion-safe-area-left: env(safe-area-inset-left);
--ion-safe-area-right: env(safe-area-inset-right);
}

Status bar overlays webview on iOS with Capacitor

I would like to achieve the same behavior of statusbar as in the capacitor example, i.e. automatically add the correct padding so my app content doesn't display inside the status bar.
However, I don't use the ionic framework but angular and the status bar overlays the webview of my application. Therefore, the content of my app is visible in the status bar.
I was expecting a method that allows to change this behavior (as the _ overlaysWebView_ method of ionic native status bar).
I also tried to add <preference name="StatusBarOverlaysWebView" value="false" /> in the config.xml file but I don't know if I should install the cordova statusbar plugin or not.
Maybe I shouldn't change this configuration and just play with padding, but then I don't know how to handle the different status bar height on different iOS devices.
I'm new to Capacitor and I never used Ionic nor Cordova. I someone could help me deal with this problem, I would be very grateful.
I have also had this issue on some applications I have worked on in the past ond only recently found a clean, less hacky way of fixing it. You will have to add the safe-area-inset-* where * can be left, right, top or bottom. This accounts for where the notch position will be when the device is either in portrait or landscape mode.
You can learn more about this by looking at this answer https://stackoverflow.com/a/47895315/4687451
You can set the padding of your directly in your css code thanks to the env variables. It works only on iOS so it can be applied on any tag you need.
body{
padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
}
This could be achieved by adding following line in CAPViewBridgeController file
webView?.frame.origin = CGPoint(x: 0, y: UIApplication.shared.statusBarFrame.size.height)
webView?.frame.size.height = UIScreen.main.bounds.size.height - UIApplication.shared.statusBarFrame.size.height;
Search for below function and update. The function should look like this
extension CAPBridgeViewController: CAPBridgeDelegate {
internal var bridgedWebView: WKWebView? {
webView?.frame.origin = CGPoint(x: 0, y: UIApplication.shared.statusBarFrame.size.height)
webView?.frame.size.height = UIScreen.main.bounds.size.height - UIApplication.shared.statusBarFrame.size.height;
return webView
}
internal var bridgedViewController: UIViewController? {
return self
}
}

Autolayout, size classes and font size

I'm currently working with the following : Swift (1.2), Xcode (6.3) and iOS 8.3.
I currently have an application that look similar to this sample I've made for this question :
For each UIButton / UILabel I would like to configure their font size depending on which device is used (iPhone 4s to iPhone 6 Plus for example).
As you can see I tried to use the "text-displaying control" in order to add a large font size (44) and another one smaller (33). For this second one, the setting is on "Width: Compact ; Height: Any".
Below are my current results :
However, as you can see, the font on the iPhone 6 Plus is still the little one. I tried to change the settings (of the little font) for "Width: Compact ; Height: Regular" and with the System font ; but the result is the same :(
How could I have something like this (iPhone 6 Plus with the large font size) ?
Is there a way to :
target specific devices with AutoLayout directly within the storyboard ?
use some tricks to make it look great (maybe with constraints and minimum font scale) ?
do it outside the storyboard (through the code) ? The only solution is to check the value of UIScreen.mainScreen().bounds.size.width ?
I just went through something like this with one of my own apps, and settled on this solution:
// global utility...
var on6plus : Bool {
return UIScreen.mainScreen().traitCollection.displayScale > 2.5
}
// and then, in my view controller's viewDidLoad...
if on6plus {
for lab in [self.scoreLabel, self.prevLabel, self.stageLabel] {
let f = lab.font
lab.font = f.fontWithSize(f.pointSize + 2)
}
}

Interface Builder: What are the UIView's Layout iOS 6/7 Deltas for?

I just noticed the iOS 6/7 Delta property found under the UIView's structs layout.
What is this for and why is this missing from AutoLayout?
Note: I noticed this question a while ago, but I'm only posting my answer now because the NDA has been lifted
Why does it not appear for AutoLayout?
As you may have noticed, iOS 7 brings about a whole new look. The look of UI elements have changed, but also so have some of their sizes (or metrics in general). This can make interface design to accommodate both iOS 7 and it's predecessors a bit of a pain.
Apple's official line is to use AutoLayout to solve this; this should take a lot of the hassle out of laying out UI elements for you. Sometimes incorporating this is not easily done, especially if you must still support iOS 5 for business reasons, or your interfaces are managed in a way that makes implementing AutoLayout difficult. As such, Apple seems to have provided a way to make your job a bit easier if you fall into this niche category, and they've called this iOS 6/7 Deltas.
Ok then, what does it do?
Whilst the label in Interface Builder is a bit unclear as to what 'Delta' means in this context, the code contained in the .xib file that corresponds to this feature is a bit more clear:
<inset key="insetFor6xAndEarlier" minX="-50" minY="-100" maxX="-50" maxY="300"/>
The key name insetFor6xAndEarlier explicitly states what this does; you can provide alternative insets for UI elements when run on iOS 7's predecessors. For example, the above defines the following delta change:
x: 50
y: 100
width: -100
height: 200
Whilst the values stored in the .xib doesn't correspond to the quoted values directly, there is a correlation between them.
x: -minX
y: -minY
width: minX + maxX
height: minY + maxY
The images below shows this change visually. It's quite an extreme example, but it's to demonstrate its ability. I would only expect in practice to have delta changes of only a few pixels.
You may notice that the values are the inverse for the iOS 6 view; this is because the deltas are relative to the type of view you're working with. If you're editing for iOS 6, the deltas there are in order to transform the element correctly for iOS 7 (the reverse of the example above).
In order to view the different styles, you can change the way Interface Builder presents it based on the OS it would be running on. This is contained within the File Inspector->Interface Builder Document (1st tab on the right bar), as so:
Does this exist if I like to code my interface by hand?
Not directly, but you can easily achieve the same effect by having conditional checks on OS version within your code, and setting the correct position/size accordingly. The delta ability exists in Interface Builder because there would be no straightforward way to have conditional positioning without having code to do it, and the point of Interface Builder is to get a much code out of the way as possible for UI.
Overall...
Apple strongly recommend that you use AutoLayout, it makes your life easier in most cases. If you can't use it (for reasons mentioned above), deltas provide you with the flexibility to position your UI elements appropriately, based on the current OS's metrics, without the need to manually reposition them in code. A good example is to adjust for the lack of status bar, but there are plenty of other use cases.
Naturally, if you're only developing for iOS7 and above, you don't need to know this feature/won't discover it. Only if you need to have iOS6 devices running your application when built with the iOS7 SDK, without autolayout, do you need deltas.
At the time of writing (21st August), I can't find any documentation regarding this feature, nor any mentions in the WWDC material. I've had a play around, and after a bit of research, that is what I've discovered.
This actually refers to the Delta between layout position from iOS6 to iOS7.
In iOS7, some views can hide the status bar or have it transparent and, in effect, it is overlaid on top of your view. So if you put a UI element at (0.0, 0.0) on iOS6, it will appear below the status bar, but on iOS7 it would appear partially covered underneath the status bar. So in that case you would want a delta that matches the status bar height (20.0 points) so that the layout looks the same in iOS6 and iOS7.
I believe this isn't needed if you use autolayout, but of course, then you lose iPad1 support, which many of us aren't willing to concede at this point in time.
I know this is already been answered, just adding a small variant hoping it could also help those who don't use auto layout and still want to support iOS 6.1 and earlier versions.
Read this Apple's Transition Guide - Supporting earlier version
Choose 'View as' to 'iOS 7.0 and Later'
Base UI for iOS 7. For iOS 6 give suitable delta value. Use preview to see how this will render in iOS 7 and iOS 6 device.
Quick steps:
Select each immediate children of root view individually and add 20px to its 'Y' value.
Then, select all immediate children collectively and give delta Y as -20px. You can also do this in batch or individually.
AutoLayout requires at least iOS 6.0. If you want to support iOS 5.0 you couldn't use AutoLayout.
And those deltas are used to help you adjust the view position on different iOS version(mainly iOS 7 and iOS version lower than 7).
I use those value to help me like this picture.
To see iOS 6/7 Delta in action, I will demo with a SegmentedControl that appears properly on both iOS 6 and iOS 7 devices.
First, select your .Xib or ViewController in Storyboard. Uncheck Use Autolayout and select "View as iOS 7 and later"
In the Interface Builder canvas, place your SegmentedControl so that its origin.y is 20. In iOS 6/7 Delta, choose -20 for DeltaY
This will make your the SegmentedControl laid below the Status Bar in both iOS 6 and iOS 7 devices
Another useful quotes from Developer’s Guide to the iOS 7 Status Bar
Deltas can be set individually for each view and work as you would
expect. If your storyboard or nib is set to view as iOS 6, then
setting the deltas will cause that view to be shifted and/or resized
by the set delta amount when run in iOS 7. Alternately, if your
storyboard or nib is set to view in iOS 7, then the deltas will be
applied when run in iOS 6
If you are using AutoLayout, then Delta is not available.
Try this (tested in iPhone 4s running iOS6):
- (void) viewWillLayoutSubviews {
//iOS 6 workaround offset
if ([[[UIDevice currentDevice] systemVersion] floatValue] < 7) {
self.view.clipsToBounds = YES;
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenHeight = 0.0;
screenHeight = screenRect.size.width;
CGRect screenFrame = CGRectMake(0, -20, self.view.frame.size.width,self.view.frame.size.height+10);
self.view.frame = screenFrame;
}
}

Resources