NavigationController, keep logo on top without transsition - ios

I have a logo that appear on top of all my UIViewController(controlled by NavigationController).
When I get the transition between UIViewController, the logo also swipe.
What I want: I want to logo(60 pixel height) to always stay. And the swipe transition to appear below the logo.
I've tried this in view delegate, but the logo also swipe :(
let logo = UIImage(named: "logo.png")
let imageView =UIImageView(image:logo)
self.navigationItem.titleView = imageView

Issue: You have the logo swiping when transiting to next VC.
Desired Result: You want to have the logo show up on each VC without the swipe animation. But still have the Swipe animation running for everything below the logo.
What I would do is make a UIScrollView and keep the logo as just a UIImageView.
If you have github repo of this app I can take a look for you.

Subclass the UINavigationController and in the viewDidLoad, configure the logo image view and add it to the navigationBar as a subview. Also, since we're adding it to the navigation bar which is only 44px in height, so a logo with a height of 60px would overflow the bounds.
class NavigationController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
let logo = UIImage(named: "logo.png")!
let imageView = UIImageView(image: logo)
let width = logo.size.width * 60 / logo.size.height
imageView.contentMode = .scaleAspectFit
imageView.frame.size = CGSize(width: width, height: 60)
imageView.center = navigationBar.convert(navigationBar.center, to: navigationBar)
navigationBar.addSubview(imageView)
}
}

Related

My navigation bar is not moving up when scrolling UITableView with background image

I have this view hierarchy on a view embedded in a UINavigationController:
When I scroll the UITableView the navigation bar is not moving up (the title is not becoming smaller) it stays like this:
If I remove the image view as background view everything works well.
My navigation is configured like this:
navigationItem.title = "Title here"
navigationItem.largeTitleDisplayMode = .always
navigationController?.navigationBar.prefersLargeTitles = true
navigationController?.navigationBar.shadowImage = UIImage()
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationController?.navigationBar.isTranslucent = true
navigationController?.navigationBar.tintColor = .white
navigationController?.navigationBar.barStyle = UIBarStyle.blackTranslucent
navigationController?.navigationBar.backgroundColor = .clear
A project demonstrating the problem is available here:
https://drive.google.com/file/d/181Aggala2ZfGN0lDjEtHWg0vobkM0iJc/view?usp=sharing
I already tried to change the insets of the tableview but it didn't work.
tableView.contentInset = UIEdgeInsets(top: navigationController?.navigationBar.height, left: 0, bottom: 0, right: 0)
Thanks!
As you discovered, to make large title fonts work as you want them to, the UIScrollView or any of its subclass needs to be the first element in the view hierarchy.
To fix your problem, you can try setting the background image to be the background of the UITableView directly.
Edit: Okay soo according to your comment you want a background behind everything including navigation bar. There is one way of achieving this and that is to subclass your UINavigationController and inside viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
let image = UIImage(named: "wallpaper")
let imageView = UIImageView(image: image)
imageView.contentMode = .scaleAspectFill
imageView.frame = UIScreen.main.bounds
//this below part is important. Make sure to set it to 0 otherwise it will cover everything else
view.insertSubview(imageView, at: 0)
}
And then make sure your UIViewController containing the UITableView has a clear color for the UIView and remove the background image from that UIViewController

Correct placement of UIImageView in UIBarButtonItem

When attempting to place a UIImageView(UIImage) into a UIBarButtonItem on a UINavigationBar, the image gets placed in the middle of the bar and also has wide fields covering the entire bar. So, doesn't look like a small button on the left.
I've tried various tricks with frame resizing, contentMode settings.
The below code is from my View Controller, which is part of the Navigation Controller stack. Added this image into Assets:
http://pluspng.com/img-png/png-hd-bike-ktm-bike-png-500.png
for testing, named it bike.png and used it in UIImage below.
override func viewDidLoad() {
super.viewDidLoad()
let image = UIImage(named: "bike")
let imageView = UIImageView(image: image)
imageView.backgroundColor = .blue //for debugging
imageView.contentMode = .scaleAspectFit
navigationItem.leftBarButtonItem = UIBarButtonItem(customView: imageView)
}
The expected result would be to have the image of the motorbike in the left, rather than in the middle. Also, no empty fields to the left and to the right (highlighted in blue for debugging) of the image.
EXPECTED (drew up in Paintbrush):
REALITY:
Ended up resolving as:
imageView.widthAnchor.constraint(equalToConstant: (navigationController?.navigationBar.frame.height)!).isActive = true

How to remove the random white space that UIScrollView is putting between subviews?

I am trying to add two custom interfaces that are UIViews to a UIScrollView in my mainStoryBoard.
both UIViews have an image inside them, the image's dimensions are equal to the view's dimensions.
This is the code I am using to add these views to my scrollView
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var myScrollView: UIScrollView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.myScrollView.frame = view.frame
for i in 0..<2{
let uiImage = UIImage(named: "\(i)")!
let view = Bundle.main.loadNibNamed("TestView", owner: self, options: nil)?.first as! UIView
view.setImage(uiImage)
let xpos = self.myScrollView.frame.width * CGFloat(i)
view.frame = CGRect(x: xpos, y: 0, width: self.myScrollView.frame.width, height: self.myScrollView.frame.height)
myScrollView.contentSize.width = self.myScrollView.frame.width * CGFloat((i + 1))
myScrollView.layer.cornerRadius = 20
myScrollView.layer.masksToBounds = true
myScrollView.addSubview(view)
}
}
}
In the TestView.swift, I have
func setImage(_ name:UIImage) -> Void{
testUIImage.image = name
testUIImage.contentMode = .scaleAspectFit
testUIImage.clipsToBounds = true
}
But when I run the app, the first View gets added fine, but when i scroll to the right, I can see that the second View is not in the Scrollview properly and there is a white space between the first and second View, almost like the space is an added view, that is pushing the second View to the right. I have paging enabled in the scrollViewer.
First Image In ScrollView
Second Image In ScrollView
As you can see, the second image is cut off on the leading edge.
This is the blank space between them:
enter image description here
I checked the width of both UIView frames, they are equal. I also checked the content size after the second iteration, it is equal to the size of both frames*2 , as it should be. But for some reason, a white black space is being added. And it only shows up after adding 2 or more subviews.

Navigation Controller image instead of text

I am trying to put a logo (png) file into my navigation controller. I found one solution that "worked" but it didn't scale down the image to fit, thus is was massive
This is the code im using thus far, but it makes the image huge
let logoImage:UIImage = UIImage(named: "logo.png")!
self.navigationItem.titleView = UIImageView(image: logoImage)
Try this:
let logo = UIImage(named: "logo.png")
let imageView = UIImageView(image:logo)
imageView.contentMode = UIViewContentMode.ScaleAspectFit //you need to set this.
self.navigationItem.titleView = imageView
And if you want to give height and width then add this:
imageView.frame.size.width = 200
imageView.frame.size.height = 45
You can do it in 2 ways: programmatically or via XCode:
An easy way is via XCode. For it, drag view from the object library and drag it to your navigation bar. Later drag into your view in navigation bar UIImageView from object library. That's all.
Or you can do all of this programmatically.
var myView = UIView()
var imageView = UIImageView()
imageView.image = UIImage(named: "your_image_here")
myView.addSubview(imageView)
navigationController?.navigationBar.addSubview(myView)

Swift: Image does not appear in the ImageView when added to a new view

For an app I am working on, the profile page has a horizontal scroll across the top, in which there are 3 views, each spanning the width of the device. On one view is the profile picture, on the other are details and the other are social links.
The problem I am getting is when I create a UIImageView called profileImage, and then assign the users profile image to this view, it all worked fine before I added this scroll view.
Then I created this scroll view, and profileImage sits in firstView, the first view of the scroll. However the image never appears, this is not just a problem with the image as I have also attempted adding default images in the assests.
var profileImage: UIImageView!
below is the code block for creating the firstView of the slide and adding the image to the image view.
let firstView = UIView(frame: CGRectMake(scrollView.frame.origin.x, scrollView.frame.origin.y, scrollView.frame.size.width, scrollView.frame.size.height))
firstView.backgroundColor = Colours.blue
scrollView.addSubview(firstView)
var img = UIImage(named: "default_image")
profileImage = UIImageView(image: img!)
profileImage.contentMode = UIViewContentMode.ScaleToFill
if let imageUrl = user.profilePictureUrl {
profileImage.hnk_setImageFromURL(imageUrl)
println("THIS IS IMAGE URL: \(imageUrl)")
}
profileImage = UIImageView(frame: CGRectMake((firstView.bounds.size.width - profileImage.frame.size.width) / 2.0, 10, 80, 80))
firstView.addSubview(profileImage)
firstView.bringSubviewToFront(profileImage)
The imageUrl appears, I know I am missing something really easy. Also I want to note that the UIImageView and the UIScrollView are not IBOutlet's but created programmatically.
You have instantiated UIImageView object twice with same name "profileImage"; so your first profileImage is being overrided by the next profileImage. Comment in the last third line and set the frame like:
profileImage.frame = CGRectMake(x,x,x,x)

Resources