With a UITabBar, I'm having a problems with text alignment when I'm in landscape mode. What's the best way to center the text up and down so its aligned with the center of the image?
I do understand that the text will be on the right in landscape mode, I'm looking to center it with the icon.
My images are custom images but I have made 1x, 2x, and 3x versions at 25x25, 50x50, and 75x75.
I have the TabBar's bottom constraint set to Superview.Bottom.
I can fix it, if I adjust every tab bar item when I'm only in landscape mode with the following code, but this seems wrong. Also not sure if this would hold up on all devices.
surveyTabBar.items![1].titlePositionAdjustment = UIOffset.init(horizontal: 0, vertical: -10)
The best solution I found was to adjust with the UIOffset, but I only adjust in landscape mode.
#IBOutlet var myTabBar: UITabBar!
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
adjustTabBarTitles()
}
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
self.adjustTabBarTitles()
}
private func adjustTabBarTitles() {
if UIDevice.current.orientation.isLandscape {
for item in self.myTabBar.items! as [UITabBarItem] {
item.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: -8)
}
} else {
for item in self.myTabBar.items! as [UITabBarItem] {
item.titlePositionAdjustment = UIOffset(horizontal: 0, vertical: 0)
}
}
}
Related
I'm not using storyboard for my app. All design I've done programatically.
Now I'm badly stuck in screen resizing. See my example code for navigation bar:-
let screenSize: CGRect = UIScreen.main.bounds
screenWidth = screenSize.width
screenHeight = screenSize.height
NameHeight = screenHeight * 0.09
NameWidth = screenWidth
navBar = UINavigationBar(frame: CGRect(x: 0, y: 30, width: NameWidth, height: NameHeight))
self.view.addSubview(navBar)
navBar.setItems([navItem], animated: false)
This navigation bar is perfectly working for both landscape and portrait.
Problem is happening:-
1) if I suddenly move my iPad from landscape to portrait or vice versa
then screen is not properly fit.
2) but if I click any button or anything then screen is properly fit.
That means when screen is refreshing then view is good.
My total app code done in this manner.
Are there any solution for my issue?
Does I need to add anything in AppDelegate which will help to reload the screnn??? or any idea please....
Help me please to overcome this issue.....
I'd have to see the code to know what the exact issue is, but you can try:
override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
// Reload Data here
self.view.setNeedsDisplay()
The below piece of code saved me:-
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
if UIDevice.current.orientation.isLandscape {
self.viewDidLoad()
}else if UIDevice.current.orientation.isFlat {
self.viewDidLoad()
} else {
self.viewDidLoad()
}
}
May be I did the wrong thing. But it saved me ...
I've implemented the iOS 11 feature prefersLargeTitles and it works just fine. Portrait mode is working as expected:
I understand the large title will always stay collapsed (small) in landscape mode and that's fine to me. The problem is when I try to change to landscape and then again to portrait, the large title should be expanded (big) by default back in portrait mode, but it won't until I scroll down a bit:
My code looks quite simple:
if #available(iOS 11.0, *) {
navigationController?.navigationBar.prefersLargeTitles = true
navigationItem.largeTitleDisplayMode = .always
}
I also tried using different values on tableView.contentInsetAdjustmentBehavior, nothing changed. I'm kind of solving it by now scrolling down the table programmatically after orientation changes, but I think that's just a (not very nice) workaround.
Is that supposed to be working as expected? Is it something left in my implementation? Is there a better workaround to this?
I faced the same issue. This worked for me.
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
navigationItem.largeTitleDisplayMode = .always
coordinator.animate(alongsideTransition: { (_) in
self.coordinator?.navigationController.navigationBar.sizeToFit()
}, completion: nil)
}
One approach could be save the maximum navigation bar height, and set it during rotation.
Something like this:
var maximumHeight: CGFloat = 0
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
guard let navigationController = navigationController else {
return
}
if maximumHeight < navigationController.navigationBar.frame.height {
maximumHeight = navigationController.navigationBar.frame.height
}
coordinator.animate(alongsideTransition: { (_) in
navigationController.navigationBar.frame.size.height = self.maximumHeight
}, completion: nil)
}
In landscape, the system knows that it must change its size, so you don't have to worry about it.
#rassar #twofish
iOS 16
First set the PrefersLargeTitles to true either on ViewDidLoad() or on the NavigationBar in the storyboard.
Then on the Navigation Controller's rootController add this:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animate { (_) in
self.navigationController?.navigationBar.sizeToFit()
}
}
I created a blurred view on top of a scroll view (from a collection view) who is displaying on all the screen when user go to the settings but when orientation change when this blurview is active, it doesn't cover all the screen. I implemented the same function to update the frame size and origin when orientation change is catched but it still doesn't work.
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
self.detailBlurView.removeFromSuperview()
if UIDevice.current.orientation.isLandscape {
print("Landscape")
detailBlurView.frame = myCollectionView.bounds
self.myCollectionView.addSubview(detailBlurView)
} else {
print("Portrait")
detailBlurView.frame = myCollectionView.bounds
self.myCollectionView.addSubview(detailBlurView)
}
saveToCoreData()
myCollectionView.reloadData()
loadData()
}
I tried to remove the view from the superview and add it again after changing orientation but still not work.
Someone can tell me why it doesn't update the blurview frame and how to fix it please ?
I am working on a UICollectionView to show list of items in Portrait mode as shown in below screen shot and implemented using UICollectionViewController.
Now I want to re-design same thing in Landscape mode as shown in below screen shot.
How can I get such a design using UICollectionView and UICollectionViewFlowLayout in Landscape mode by re-using same code base of portrait? Is it possible? can you please advice me?
Thanks in advance.
You can also do by using stackview. Create a stackview with two views then change the axis when orientation change. Set proper constraints for your requirement.
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
handleOrientationForLandscape(isLandscape: UIDevice.current.orientation.isLandscape)
}
func handleOrientationForLandscape(isLandscape: Bool) {
if isLandscape
{
containerStackview.axis = .horizontal
topViewWidthConstraint.constant = 700
}else
{
containerStackview.axis = .vertical
topViewWidthConstraint.constant = UIScreen.main.bounds.width
}
}
please check https://github.com/karthikprabhuA/stackOverflowAnswer
I have a full-screen UIView. When I rotate the phone the view shrinks a little (and you see the black background) and then expands again to be full-screen. It basically animates as expected.
The other views on the screen also animate accordingly.
Can I prevent this from happening for one specific view?
I would like the full-screen view to just stay full-screen without animation revealing the black background, but maintain that the other views animate their rotation.
Kind of like how Apple does it in the camera app. The "viewfinder" does not animate its rotation, but the buttons do.
I have the following code in my ViewController. liveView is the the full-screen UIView mentioned.
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animateAlongsideTransition(in: self.liveView, animation: { (context) in
if let connection = (self.liveView.layer as! AVCaptureVideoPreviewLayer).connection {
connection.videoOrientation = AVCaptureVideoOrientation(ui: UIApplication.shared.statusBarOrientation)
}
}, completion: nil)
}
AVCaptureVideoOrentation is an extension which basically translates UIInterfaceOrientation to AVCaptureVideoOrientation with a switch statement.
Thanks
- Joseph
Did you try self.liveView.layer.removeAllAnimations():
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
coordinator.animateAlongsideTransition(in: self.liveView, animation: { (context) in
if let connection = (self.liveView.layer as! AVCaptureVideoPreviewLayer).connection {
connection.videoOrientation = AVCaptureVideoOrientation(ui: UIApplication.shared.statusBarOrientation)
}
self.liveView.layer.removeAllAnimations()
}, completion: nil)
}