Swift - Adding touch to UIImageView - ios

I'm following a tutorial online and I'm trying to add touch detection to an UIImageView. I realize that this can be done with a gesture recognizer but I have a different problem and I don't know how to ask for it.
Basically, I added an overlay UIButton initialized from the frame of imageView. However, I have to move the frame down 64 px because of the navigation bar. My imageView is added form the storyboard but UIButton is added programmatically.
Is there a way to do this without adding 64 px manually? This is no biggies but since the frame of the imageView when printing is (10, 10, 355, 450) and the frame of UIButton is (10, 74, 355, 450), it kinda ticks me off a little bit.
Let me clarify, I'm wondering why view controller doesn't take into account the size of the navigation bar when adding subview programmatically? It seems to handle this just fine when adding subview from Storyboard.
Without adding 64px:
overlay = UIButton(frame: imageView.frame)
overlay.backgroundColor = UIColor.red
overlay.addTarget(self, action: #selector(imageViewTapped), for: .touchUpInside)
view.addSubview(overlay)
With 64px added - fits perfectly
overlay = UIButton(frame: imageView.frame.offsetBy(dx: 0, dy: 64))
overlay.backgroundColor = UIColor.red
overlay.addTarget(self, action: #selector(imageViewTapped), for: .touchUpInside)
view.addSubview(overlay)

You can add button on image view.
Try This :
let overlay = UIButton(frame: imageView.bounds)
imageView.isUserInteractionEnabled = true
overlay.backgroundColor = UIColor.red.withAlphaComponent(0.3)
overlay.addTarget(self, action: #selector(imageViewTapped), for: .touchUpInside)
imageView.addSubview(overlay)

You can use UITapGestureRecognizer for the same as given below.
let bg = UIImageView(image: UIImage(named: "Home"))
bg.frame = self.view.frame
self.view.addSubview(bg)
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(SecondViewController.onTapScreen))
bg.isUserInteractionEnabled = true
bg.addGestureRecognizer(tapRecognizer)
Handle tap event as given below
func onTapScreen() {
// Handle touch here.
}
By this way you don't need to use button also so it can avoid multiple controls.

Set your UIViewController's navigationbar to Opaque Navigation Bar. It will start you view below navigation bar.

Related

show title and image in navigation bar button

I would like to show the button and image in the navigation bar.
Using this
let action = UIAction { _ in }
let image = UIImage(named: "logout")
let doneButton = UIBarButtonItem(title: "Done", image: image, primaryAction: action, menu: menu)
navigationItem.leftBarButtonItem = doneButton
Just shows the image without the title.
The documentation
https://developer.apple.com/documentation/uikit/uibarbuttonitem/3600776-init
Only indicates that if title is nil it would not be displayed.
I tried
https://stackoverflow.com/a/54403576/1898829 same result
https://stackoverflow.com/a/3903348/1898829 one loses a lot of default behaviour and cant use the uiaction with the new apis.
While I can definitely find a work around but any work around is less than ideal.
UIBarButtonItem doesn't support both text and image in the same UIBarButtonItem. There are 3 approach to solve this problem:
Make your self a custom navigation controller
Make an image which combine both your text and your image
Make your text and image into a custom view. UIBarButtonItem support a custom View. Check example below for how to use. You can customize the View both in coding or using autolayout view for your choice
let view = UIView(frame: CGRect(origin: .zero, size: CGSize(width: 50, height: 50)))
let gesture = UITapGestureRecognizer(target: self, action: #selector(tapInView))
view.addGestureRecognizer(gesture)
view.backgroundColor = .red
self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: view)
#objc func tapInView() {
print("tap")
}

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

Why BarButton Item with custom view stretches because of image? [duplicate]

I am trying set size programmatically of left button bar item but i can't it.
This is my code:
let backButton = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
backButton.setBackgroundImage(UIImage(named: "hipster_pelo2.png"), for: .normal)
self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: backButton)
But this is the result in iphone X with Xcode 9 and swift 3. In the image, you can see title app move it to the right because button size:
Anybody know that the problem will be the image size??
You can restrict the size of barButton items using
let barButton = UIBarButtonItem(customView: backButton)
NSLayoutConstraint.activate([(barButton.customView!.widthAnchor.constraint(equalToConstant: 30)),(barButton.customView!.heightAnchor.constraint(equalToConstant: 30))])
self.navigationItem.leftBarButtonItem = barButton
Reference : https://skyebook.net/blog/2017/09/uibarbuttonitem-sizing-in-ios-11/
The huge frame of the button is because of the huge image you are setting to the button's background. Though frame you set to button should override the implicit size of the button, for some strange Reasons when passed as custom view to bar button implicit size takes over. Hence applying width and height constraints to restrict the size of custom view kind of becomes necessary.
EDIT:
As OP is facing issue with loading the image from url and setting it as button's image I am updating my answer to demonstrate the same,
do {
try button.setImage(UIImage(data: Data(contentsOf: your_url)), for: .normal)
}
catch {
print(error)
}
Issue with OP's code was trying to set the button image, even before the image was downloaded. So this should help you solve your problem :)
EDIT 2:
OP facing trouble with making the bar button's customView circular, so here is the code that should make BarButton item's customView circular :)
barButton.customView?.layer.cornerRadius = 15
barButton.customView?.layer.masksToBounds = true
Hope it helps

How can I set size leftBarButtonItem?

I am trying set size programmatically of left button bar item but i can't it.
This is my code:
let backButton = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
backButton.setBackgroundImage(UIImage(named: "hipster_pelo2.png"), for: .normal)
self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: backButton)
But this is the result in iphone X with Xcode 9 and swift 3. In the image, you can see title app move it to the right because button size:
Anybody know that the problem will be the image size??
You can restrict the size of barButton items using
let barButton = UIBarButtonItem(customView: backButton)
NSLayoutConstraint.activate([(barButton.customView!.widthAnchor.constraint(equalToConstant: 30)),(barButton.customView!.heightAnchor.constraint(equalToConstant: 30))])
self.navigationItem.leftBarButtonItem = barButton
Reference : https://skyebook.net/blog/2017/09/uibarbuttonitem-sizing-in-ios-11/
The huge frame of the button is because of the huge image you are setting to the button's background. Though frame you set to button should override the implicit size of the button, for some strange Reasons when passed as custom view to bar button implicit size takes over. Hence applying width and height constraints to restrict the size of custom view kind of becomes necessary.
EDIT:
As OP is facing issue with loading the image from url and setting it as button's image I am updating my answer to demonstrate the same,
do {
try button.setImage(UIImage(data: Data(contentsOf: your_url)), for: .normal)
}
catch {
print(error)
}
Issue with OP's code was trying to set the button image, even before the image was downloaded. So this should help you solve your problem :)
EDIT 2:
OP facing trouble with making the bar button's customView circular, so here is the code that should make BarButton item's customView circular :)
barButton.customView?.layer.cornerRadius = 15
barButton.customView?.layer.masksToBounds = true
Hope it helps

remove gap between buttons in navigation item rightbuttonitems

I'm using self.navigationItem.rightBarButtonItems to setup my navigation bar items. However, for the bar buttons, i'm using a custom view(button). I observe there is spacing between buttons. How can I remove this?
i know its too late, but i solved it using following method of UIBarButtonItem
use
[barbuttonitem setImageInsets:UIEdgeInsetsMake(0, -30, 0, -70)];
I solved this by using storybord interface.I know you are using custom Bar,but this answer will useful for those who use stroybord.
1.Select the Bar item.
2.Select the Size Inspector.
Here you can find image Inset,using top,bottom AND left , right you can change the position of Bar Item.
You can't remove it. You can work around it by creating a bar button item with a custom view, where that custom view has you custom buttons all added as subviews. In this way you can directly control the exact positioning.
Here is an example that how you can resolve this issue:
Create an extension of UIBarButton
extension UIBarButtonItem
{
/** Create custom right bar button for reduce space between right bar buttons */
func initRightButton(let imageNamed:String, let target:UIViewController, let selector:Selector) -> UIBarButtonItem {
let frame = CGRectMake(0, 0, 30, 30)
//Create imageView
let imageView = UIImageView(frame:frame)
imageView.image = UIImage(named: imageNamed)
//Create Button
let button = UIButton(frame: frame)
button.addTarget(target, action: selector, forControlEvents: .TouchUpInside)
//Create View and add imageView and Button
let view = UIView(frame: frame)
view.addSubview(imageView)
view.addSubview(button)
return UIBarButtonItem(customView: view)
}
}
In your class controller use the method customizeNavigationBar
func customizeNavigationBar() {
//Create custom right bar button chat for reduce space between right bar buttons
let barButton1 = UIBarButtonItem().initRightButton("customImageNamed1", target: self, selector: customSelector)
let barButton2 = UIBarButtonItem().initRightButton("customImageNamed2", target: self, selector: customSelector)
self.navigationItem.rightBarButtonItems = [barButton1,barButton2]
}

Resources