Xcode how to add buttons to an image view - swift

What approach would I take to add buttons to an image in xcode? The app is for iPhones and iPads so it needs to be "responsive" somehow. I am trying to do something like this image has sample image map I found a Github project that uses Obj-C, but I am just trying to learn app development and have no idea what I am doing. Eventually, once the button is pressed I will make some kind of popup with an image and a little info. My app is in swift. I would appreciate and tips or direction to tutorials.

Assuming that provided Map is one flat image.
This is sudo and it will explain you the concept.
Works for both iPhone or iPad on different screen sizes.
//make sure you have the correct size of original image.
let originalImageSize: CGSize = CGSize(width: 1000, height: 500)
//Lets create a struct to have the basic information we need
struct Item {
var id: Int
var name: String
var x: Double
var y: Double
}
//Creating some sample button on the map
//x and y are based on the original Image size
let buttonsInfo : [Item] = [
Item(id: 1, name: "France", x: 10, y: 10),
Item(id: 2, name: "Poland", x: 20, y: 30),
Item(id: 3, name: "Location A", x: 50, y: 100),
Item(id: 4, name: "Location B", x: 300, y: 300)
]
//sudo code : plug it with your project real image code
let yourUIImageView = UIImageView(image: UIImage())
//after the image is rendered on UI get the real dimensions
//Size of the Image that is rendered on UI in proper aspect ratio
let renderedImageSize: CGSize = CGSize(width: 500, height: 250)
for item in buttonsInfo {
let button = UIButton()
button.tag = item.id
//
button.frame = CGRect(x: Double(renderedImageSize.width/originalImageSize.width)*item.x,
y: Double(renderedImageSize.height/originalImageSize.height)*item.y,
width: 50, height: 50)
button.backgroundColor = UIColor.red
button.setTitle("Name your Button ", for: .normal)
button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
//yourUIImageView is actual view in your code
yourUIImageView.addSubview(button)
}
func buttonAction(sender: UIButton!) {
let item:Item = buttonsInfo.filter{$0.id == sender.tag}
print("Button tapped")
print(item)
}
Note: if you are resizing your yourUIImageView on orientation changes, then you need to do few more changes to move the buttons based on the new aspect ratio. (let us know if you need help)

You can use UITapGestureRecognizer over the image view to perform same as button action
1st Put in viewDidLoad
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(YourViewControllerName.imgAction))
ImageViewName.addGestureRecognizer(tap)
2nd write function to perform action
func imgAction(){
// perform the action here
}

There are two approaches
1. You can add image to a button as shown in the picture
You can place an image in the storyboard and then add a button above it, then remove the text of the button. It's better to add both these things in a UIView so you can make sure that the button is exactly above the image. You can set the constraints for the UIView after that add the image and button and set the constraints of top, left, right and bottom to 0
Note: Make sure that the button is always above the image so it's clickable. Try to color the button in storyboard in order to be certain.

Related

Swift , UIkit - Add collection view to toolBar, GalleryApp

i want to create a photo gallery view. I would like to look like a photo gallery in iPhone.
I have a problem with adding a collection view to toolbar. If I add only one image as UIImageView , everything works but when I add collection view, view not appear
This is my code - help
let toolbar = ToolBarCollectionView()
toolbar.view.translatesAutoresizingMaskIntoConstraints = false
toolbar.view.frame = navigationController?.toolbar.frame ?? CGRect(x: 0, y: 0, width: 25, height: 25)
let item = UIBarButtonItem(customView: toolbar.view)
setToolbarItems([item], animated: false)
navigationController?.toolbar.setShadowImage(UIImage(), forToolbarPosition: .bottom)

Button with multiple accessible labels and images in Swift

I need to create custom button class, reuse it 4 times and I also need to override its text and image name. My next problem is how to set its frame somehow dynamically (now it is static), because I need this 4 buttons in grid 2x2.
I'm trying to create button exactly like this: https://imgur.com/a/dNhUGhc.
I have coded this but it is static and in ViewController I can't edit (override) these labels and image name. And if I tried to reuse this class I would have them in the same spot, because frame settings is exactly the same.
I'm subclassing UIButton. If something more suitable exists just let me know.
Code for adding label
// city label
let cityRect = CGRect(x: 0, y: 20, width: buttonWidth, height: 25)
let cityLabel = UILabel(frame: cityRect)
cityLabel.text = "Label"
cityLabel.font = UIFont.systemFont(ofSize: 17, weight: .semibold)
cityLabel.textAlignment = .center
addSubview(cityLabel)
Code for adding image
// image
let imageView = UIImageView(image: UIImage(named: "something"))
imageView.frame = CGRect(x: 0, y: 60, width: 40, height: 40)
imageView.center.x = self.center.x - 20
addSubview(imageView)
Can you guys help me? Thanks
It looks like what you need to do is use an IBOutlet. Basically, an IBOutlet will give you a reference within your code (custom UIView or UIViewController subclass) to the button that you've setup in xib or storyboard. Then you can make any changes or adjustments that you want to it at runtime.
Check this out to learn more about IBOutlets and how to set them up in your project.

How to calculate touching figure sizes swift 3

I'm currently making a scanner app with Swift3, I need to calculate touching figure size in UIView, Now I'm leaving a question. Please inform me How to calculate touching figure sizes and how to resolve.
I am not sure about the question but perhaps this could help you:
let button = UIButton.init(frame: CGRect.init(x: 0, y: 0, width: 100, height: 100))
button.addTarget(self, action: #selector(btnClicked(sender:)), for: .touchUpInside)
func btnClicked(sender: UIButton){
//Here you have the size of a button touched
let figure_touched_height = sender.frame.size.height
let figure_touched_width = sender.frame.size.width
}

Positioning a NSImage within a NSButton

I have an NSButton, created programatically. within said button, I have an NSImage that serves as an icon:
let button = NSButton(frame: NSRect(x: 10, y: (200 + (50 * id)), width: 100, height: 50))
button.action = #selector(self.switchToView)
let img = NSImage(named: "wob_icon")
button.image = img
What I'm trying to do is get the image 10pt. from the left side of the button, while centred vertically. So far, the image shows up centered horizontally as well as vertically, but since it doesn't seem like I'm able to define a frame or something like that, I can't really move it.
Is there a way to move the image within it's parent (the button)?
Thanks.
Maybe you could use the imagePosition property on a NSButton? (documented here).
It uses an enum of type NSCellImagePosition (documented here) and allows you to set the image to the left of the text, to the right of the text, above the text, below the text and so on.
You still won't have the opportunity to align things pixel perfect but if you can live with that, then imagePosition seems like the way to go.
Here is how to use it:
let button = NSButton(frame: NSRect(x: 10, y: 10, width: 100, height: 50))
button.action = #selector(self.switchToView)
let img = NSImage(named: "wob_icon")
button.image = img
button.imagePosition = .imageLeft
button.title = "Look left :)"
And that gives me this stunning UI:
Hope that helps you.

How to get action of button in Swift MacOS

I am trying to set up zoom for a game where you click on a button to zoom in, and another to zoom out (which will be part of the UI).
I am having problems getting the input of the buttons to the code. I can read that the button is not pressed, but I cannot figure out how to read if it is pressed.
Looking through the API reference gave me the idea to try using the "state" of the button, but it always returns 0, even when the button is pressed. This could be because the update function does not update as fast as the button's state changes.
Here is my code:
class GameScene: SKScene {
override func sceneDidLoad() {
cam = SKCameraNode()
cam.xScale = 1
cam.yScale = 1
self.camera = cam
self.addChild(cam)
cam.position = CGPoint(x: 0, y: 0)
setUpUI()
}
func setUpUI(){
let button1Rect = CGRect(x: 20, y: 80, width: 80, height: 40)
let zoomIn = NSButton(frame: button1Rect) //place a button in the Rect
zoomIn.setButtonType(NSMomentaryPushInButton)
zoomIn.title = "Zoom In"
zoomIn.alternateTitle = "Zoom In"
zoomIn.acceptsTouchEvents = true
view?.addSubview(zoomIn) //put button on screen
let button2Rect = CGRect(x: 20, y: 30, width: 80, height: 40)
let zoomOut = NSButton(frame: button2Rect) //place a button in the Rect
zoomOut.setButtonType(NSMomentaryPushInButton)
zoomOut.title = "Zoom Out"
zoomOut.alternateTitle = "Zoom Out"
zoomOut.acceptsTouchEvents = true
view?.addSubview(zoomOut) //put button on screen
if zoomIn.state == 1{ //this loop is never true no matter how many times I press the button
print("zoom")
}
}
}
I did cut out some of the code involving the mouse as it is not relevant.
Answer is from TheValyreanGroup.
Simply define the button outside of the setUpUI() function (outside of the GameScene or within it works, outside of the GameScene is easier).