UITableviewCell show extra label in when device in landscape - ios10

I'm trying to achieve the following:
In a UITableViewCell I have an StackView with 3 labels, but I wanna show only two of them in portrait and all of them when in landscape mode.
What I've tried to do was: add a customization for the installed property that's only checked when the device is in CxC... But when I run the app and rotate the emulator I get this on the debug: pending: position from NSPoint: {36.5, 15} to Optional(NSPoint: {40.5, 15})
I've attached an image show what I want to achieve.
Thanks a lot]1

You can find orientation by getting device orientation status and hide the third label
if UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeLeft{
cell.thirdLabel.hidden = false
}
else if UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeRight{
cell.thirdLabel.hidden = false
}
else if UIDevice.currentDevice().orientation == UIDeviceOrientation.UIDeviceOrientationPortraitUpsideDown{
cell.thirdLabel.hidden = true
}
else if UIDevice.currentDevice().orientation == UIDeviceOrientation.UIDeviceOrientationPortrait{
cell.thirdLabel.hidden = true
}
You can use the two and remove others

Related

Dynamically assigned UIFont does not show immediately in slow simulator

I have a UIView with a UILabel for which, I'd like allow the user to dynamically change the font size. The code below almost works, but the problem is that after the new UIFont is assigned to the label, it doesn't immediately show in the UI. Instead, some other UI activity is required to make it show up.
What I'm looking for is a technique where the font change will show up immediately after the gesture is over.
Starting with the technique shown in this tutorial, I added a gesture recognizer to the UIScrollView. In the associated UIViewController, I implemented handlePinch(UIpinchGestureRecognizer).
Inside that function, I take action only when the gesture begins and ends (no attempt to animate). If the user indicated zoom, I increase the font by 4 points. If the user indicated a shrink, I decrease the font by 4 points. This all works, except for the fact that the screen does not reflect the change until another UI function is executed. I have only tested this on the simulator, but I presume it would be the same on a real device.
I have tried setNeedsDisplay and setNeedsLayout and several other odd things on both the UILabel as well as the view that was passed to the handlePinch() function.
#IBAction func handlePinch(_ gesture: UIPinchGestureRecognizer) {
guard let gestureView = gesture.view else {
return;
}
gestureView.transform = gestureView.transform.scaledBy(x: gesture.scale, y: gesture.scale)
if (gesture.state == UIPinchGestureRecognizer.State.began) {
pinchD = gestureView.transform.d
print("pinch started ", pinchD)
}
if (gesture.state == UIPinchGestureRecognizer.State.ended) {
print("pinch ended ", gestureView.transform.d)
print("compare:", pinchD, gestureView.transform.d)
let larger = gestureView.transform.d > pinchD
let fontSize = multiLineLabel.font.pointSize
if (larger) {
if (fontSize < 28) {
let calculatedFont = UIFont(name: multiLineLabel.font.fontName, size: fontSize + 4)
print("bigger fontSize", fontSize + 4);
multiLineLabel.font = calculatedFont
}
} else {
if (fontSize > 12) {
let calculatedFont = UIFont(name: multiLineLabel.font.fontName, size: fontSize - 4)
print("smaller fontSize", fontSize - 4);
multiLineLabel.font = calculatedFont
}
}
}
}
What needs to be done after the calculatedFont is applied to the UILabel to make it show immediately in the app?
ADDITIONAL CLARIFICATION:
handlePinch() runs as expected; every time a pinch gesture ends, I see bigger fontSize... or smaller fontSize... logged.
After the logging, the simulator screen font size remains the same until I do one of several things. One thing that causes the font size to change is if I swipe to the next item. Before the animation starts, the font increases. The font changes also if I hit the back button (the font change shows briefly before the other view appears).
It turns out that my presumption was incorrect:
I have only tested this on the simulator, but I presume it would be the same on a real device.
I believe that was NOT correct.
I'm testing on a very, very old iMac and the simulator is bogged down such that it takes 15 or 30 seconds to update the screen!
So I conclude that the code is working fine after all.

TraitCollectionDidChange behaves different for iphone X

In My case i am changing my layouts of the view depending on the traitCollection.horizontalSizeClass
Here is my Code snippet .
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if traitCollection.horizontalSizeClass == .regular {
// 2
NSLayoutConstraint.deactivate(compactConstraints)
NSLayoutConstraint.activate(regularConstraints)
// 3
socialMediaView.axis = .horizontal
} else {
// 4
NSLayoutConstraint.deactivate(regularConstraints)
NSLayoutConstraint.activate(compactConstraints)
socialMediaView.axis = .vertical
}
}
Every things working as directed in iphone 7 plus and iphone x in portrait-mode
and in landscape mode i want the rabbit image comes to left side and the stackview of all socialMedias axis will be horizontal
but in iphone X landscape mode its not coming while in phone 7 its coming .Check the below screen shots
Looking at your question and condition, I found a problem in your condition. you should check for the verticalSizeClass instead of horizontalSizeClass.
WHEN CHECK FOR HORIZONTAL SIZE CLASS.
IN PORTRAIT: All iPhone Devices has compact width, so every time, it will go to else condition and set the view properly.
IN LANDSCAPE: All iPhone Plus (iPhone 6s Plus, iPhone 7 Plus and iPhone 8 plus) Devices has Regular width and All other iPhone (iPhone 6s, 6SE, iPhone 7 and iPhone 8, iPhone X) Devices has Compact width, so for all plus devices it will works fine but not for others.
FOR PORTRAIT:
FOR LANDSCAPE:
For more, read official doc here
So, update your code to this.
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
if traitCollection.verticalSizeClass == .regular {
NSLayoutConstraint.deactivate(compactConstraints)
NSLayoutConstraint.activate(regularConstraints)
socialMediaView.axis = .horizontal
} else {
NSLayoutConstraint.deactivate(regularConstraints)
NSLayoutConstraint.activate(compactConstraints)
socialMediaView.axis = .vertical
}
}
Try and share the results.

App changes to different controller view when changing orientation

I'm developing an app using Xcode 9.2 and swift 4 and I needed to allow just one view in my app to change to landscape, so I added the code below to my AppDelegate
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
if globalVariables.gIsDosageView == "Y" {
if UIDevice.current.orientation == .landscapeLeft || UIDevice.current.orientation == .landscapeRight {
return UIInterfaceOrientationMask.all;
} else {
return UIInterfaceOrientationMask.portrait;
}
} else {
return UIInterfaceOrientationMask.portrait;
}
}
The global variable is set to "N" on every other controller and so only DosageView has it set to "Y". In the DosageView controller I added this method to help with the transition.
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
hideViews()
if size.width < 400 {
DispatchQueue.main.async() {
self.userImg.isHidden = false
self.burgerImg.isHidden = false
self.deviceImg.isHidden = false
self.portraitView.isHidden = false
self.landscapeView.isHidden = true
}
}
else {
DispatchQueue.main.async() {
self.userImg.isHidden = true
self.burgerImg.isHidden = true
self.deviceImg.isHidden = true
self.portraitView.isHidden = true
self.landscapeView.isHidden = false
self.loadLandscapeView()
}
}
}
I've set up a LandscapeView and a PortraitView and the method above helps to toggle between them and it all works fine. If I move to the next view or return to the main screen and then return to the DosageView and then change the orientation to Landscape it works but if I go to the next view and then from there to the Connect view and connect (via BLE, NFC or QR) it then returns to the DosageView. When I change the orientation to Landscape it changes back to the Connect view. There is no direct link between these two views as you have to go through the Instruction view to get to Connect View for the DosageView, so how can this happen?
When I run it under debug and put a breakpoint in the ViewDidLoad on Connect View, it runs every time the DosageView changes to Landscape. If anyone can tell me what is going on I would be grateful as this is driving me crazy.
It was actually a colleague who sorted this for me and as he correctly pointed out it was a Lottie run call causing the problem. For anyone using Lottie and experiencing this problem, simply check your animation code. I had originally plagiarised code from a Splash screen as below
splashAnimation!.loopAnimation = false
splashAnimation!.play(fromProgress: 0,
toProgress: 1.0,
withCompletion: { (finished) in
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let controller = storyboard.instantiateViewController(withIdentifier: "Menu")
self.present(controller, animated: true, completion: nil)
})
This code works fine as it moves on to the main screen on completion. However, the screen that was causing the problems moves between two different screens and to fix the problem, my colleague simply removed the withCompletion part as below
splashAnimation!.loopAnimation = true
splashAnimation!.play(fromProgress: 0,
toProgress: 1.0)

how to set orientation for each scene in unity3d

I have 4 scenes in my game
I need to set scene 1 and scene 3 in landscape mode, scene 2 and scene 4 in portrait mode
how can I do this?
please help me out...
I'm searching for a long time but couldn't find out the answer
You can have a script that checks for the actual level and changes the orientation in according to the retrieved value.
As an example:
function Start(){
if (Application.LoadedLevel == 1)
Screen.orientation = ScreenOrientation.LandscapeLeft;
else if (Application.LoadedLevel == 2)
Screen.orientation = ScreenOrientation.Portrait;
//...
}
More info about usage and orientation values.
Since around Unity 5.3 there is a new API for getting the current scene.
This example forces the screen orientation on mobile devices to portrait on a scene called "GameView" and landscape otherwise.
using UnityEngine;
using UnityEngine.SceneManagement;
public class ScreenOrientationScript : MonoBehaviour {
void Start () {
if (Application.isMobilePlatform == true) {
if (SceneManager.GetActiveScene().name == "GameView") {
Screen.orientation = ScreenOrientation.Portrait;
} else {
Screen.orientation = ScreenOrientation.Landscape;
}
}
}
}
Sample iOS setting to allow orientations
Unity uses single/sole activity for ALL Levels/Scenes, which is com.unity3d.player.UnityPlayerActivity, as can be found in AndroidManifest.xml file.
So all you need do is to specify the orientation in the Player Setting Inspector (Default Orientation part):

Detect direction of UIScrollView scroll in scrollViewWillBeginDragging

I did google enough, & I did check posts like these ( Finding the direction of scrolling in a UIScrollView? ) in stackoverflow before posting this. I have a dynamic number of photos in an iPhone App, that am displaying through UIScrollView. At any point in time, I have only 3 photos being displayed in the scroll-view. When I have, say 4 photos, in total:
1st photo : displayed at offset 0.0
2nd photo : displayed at offset 320.0
3rd photo : displayed at offset 640.0
Now, when the user scrolls to the 4th photo, the scroll-view resets to 0.0 offset. If the user tries to scroll 'beyond' the 4th photo, scrolling should stop in the right-direction only (so that user doesn't scroll 'beyond'). But currently, the user 'is able' to scroll beyond the last photo ; however, I detect this programmatically & reset the offset. But it doesn't look neat, as the user sees the black background momentarily. I want to detect that the user has started scrolling 'right' (remember, scrolling 'left' i.e. to the 'previous' photo is okay) in scrollViewWillBeginDragging, so that I can stop any further scrolling to the right.
What I tried:
Trying using self.scrollView.panGestureRecognizer's
translationInView isn't working, because there is no
panGestureRecognizer instance returned in the first place (!),
though the UIScrollView API claims so.
Detecting this in scrollViewDidEndDecelerating is possible, though
it'll not serve my purpose.
I had no issues determining direction in scrollViewWillBeginDragging when checking the scroll view's panGestureRecognizer:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
CGPoint translation = [scrollView.panGestureRecognizer translationInView:scrollView.superview];
if(translation.y > 0)
{
// react to dragging down
} else
{
// react to dragging up
}
}
I found it very useful in canceling out of a scroll at the very first drag move when the user is dragging in a forbidden direction.
Swift 3 Solution
1- Add UIScrollViewDelegate
2- Add this code
func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
let actualPosition = scrollView.panGestureRecognizer.translation(in: scrollView.superview)
if (actualPosition.y > 0){
// Dragging down
}else{
// Dragging up
}
}
For swift 2.0+ & ios 8.0+
func scrollViewWillBeginDecelerating(scrollView: UIScrollView) {
let actualPosition = scrollView.panGestureRecognizer.translationInView(scrollView.superview)
if (actualPosition.y > 0){
// Dragging down
}else{
// Dragging up
}
}
Thank you, Kris. This is what worked for me, finally:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
// Detect the scroll direction
if (lastContentOffset < (int)scrollView.contentOffset.x) {
...
}
}
This is what I used and it works nicely at least on iOS 6.0:
- (void)scrollViewDidScroll:(UIScrollView*)scrollView
{
CGPoint translation = [scrollView.panGestureRecognizer translationInView:scrollView];
// Detect direction by accessing x or y of translation
}
Saves you the instance variable for lastContentOffset ...
Take a look at scrollViewWillEndDragging:withVelocity:targetContentOffset:.
You can use that method do do any checking and see if it is going where it should not and then in the method you can set a new targetContentOffset.
Per the documentation:
This method is not called when the value of the scroll view’s pagingEnabled property is YES. Your application can change the value of the targetContentOffset parameter to adjust where the scrollview finishes its scrolling animation.
There seem to be issues with detecting scroll direction based on the translation of the scrollView's pan recognizer in iOS 7+. This seems to be working pretty seamlessly for my purposes
func scrollViewDidScroll(scrollView: UIScrollView) {
if !scrollDirectionDetermined {
let translation = scrollView.panGestureRecognizer.translationInView(self.view)
if translation.y > 0 {
println("UP")
scrollDirectionDetermined = true
}
else if translation.y < 0 {
println("DOWN")
scrollDirectionDetermined = true
}
}
}
func scrollViewWillBeginDragging(scrollView: UIScrollView) {
scrollDirectionDetermined = false
}
func scrollViewDidEndDecelerating(scrollView: UIScrollView) {
scrollDirectionDetermined = false
}
scrollView.panGestureRecognizer translationInView:scrollView doesn't report anything useful in scrollViewWillBeginDragging in iOS 7.
This does:
In the #interface
BOOL scrollDirectionDetermined;
and:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (!scrollDirectionDetermined) {
if ([scrollView.panGestureRecognizer translationInView:scrollView.superview].x > 0) {
//scrolling rightwards
} else {
//scrolling leftwards
}
scrollDirectionDetermined = YES;
}
}
and:
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
scrollDirectionDetermined = NO;
}
Building off of #Oscar's answer, you can do things like
scrollView.bounces = actualPosition.y < 0 if you want the scrollView to bounce when you scroll to the bottom but not when you scroll to the top