How to Center a UIButton in a TableViewCell? - ios

I would like to make my custom button to center in tableView Cell, because It feels like the button somehow offset to the left (I think it's because of the frame for accessory type.
I have tried using the didselectrowatindexpath but I feel like I want to do it with UIButton. Do you have any idea how to make my button in tableviewcell center? I have tried using self.view.center but it doesn't work. here's the code:
self.buatAkunBtn = UIButton(frame: CGRectInset(self.buatAkunBtnCell.contentView.bounds, 0, 0))
self.buatAkunBtn.setTitle("Masuk", forState: UIControlState.Normal)
self.buatAkunBtn.setTitleColor(acehBusColor, forState: .Normal)
self.buatAkunBtn.addTarget(self, action: Selector("btncreateAccTapped:"), forControlEvents: .TouchUpInside)
self.buatAkunBtnCell.addSubview(self.buatAkunBtn)
Here's the image from which caused by the code above:

METHOD 0:
If you absolutely want to use code. Here is how I would solve your case:
self.buatAkunBtn = UIButton(frame: CGRectInset(self.buatAkunBtnCell.contentView.frame.offsetBy(dx: 30, dy: 0), 0, 0))
self.buatAkunBtn.setTitle("Masuk", forState: UIControlState.Normal)
self.buatAkunBtn.setTitleColor(acehBusColor, forState: .Normal)
self.buatAkunBtn.addTarget(self, action: Selector("btncreateAccTapped:"), forControlEvents: .TouchUpInside)
self.buatAkunBtnCell.addSubview(self.buatAkunBtn)
Or you can use the Interface builder which would be much simpler and elegant.
METHOD 1:
1) Click on your UIButton.
2) Add constraints relative to Cell 0 to left, 0 to right.
3) Your UIButton is now centered.
METHOD 2 (recommended):
1) Click on your UIButton.
2) Ctrl drag from your button to your cell.
3) Select "center horizontally in container".
METHOD 3 (recommended):
1) Click on your UIButton.
2) Click on the alignment constraint icon at the bottom right.
3) Click on the checkbox: "center horizontally in container"

Related

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

Swift - Adding touch to UIImageView

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.

How to make one UIButton, UILabel, & UITextField control all input

Currently I am working on my first iOS app, a ToDo Planner. Here is the layout for it.
Right now I have it set up in that each line has its own textField, button (checkmarked circle), and label (strike line). Like this:
if(textField == textField1) // if the first text field is pressed
{
let image = UIImage(named: "To Be Completed Circle.png")
button1 = UIButton(frame: CGRect(x: 340, y: 56, width: 30, height: 30));
button1.setBackgroundImage(image, for: UIControlState.normal)
self.view.addSubview(button1)
button1.addTarget(self, action:#selector(self.pressCheck), for: .touchUpInside)
}
And this:
if(button == button1) // if first button was pressed
{
button1.setBackgroundImage(image, for: UIControlState.normal) //set image to be of circle with checkmark
button1.removeTarget(nil, action: nil, for: .allEvents) //remove old target action
button1.addTarget(self, action:#selector(self.pressUnCheck), for: .touchUpInside) //add new target action for removing checkmark
self.view.addSubview(button1)
textField1.textColor = UIColor.gray //change textfield to a gray color
label1 = UILabel(frame: CGRect(x : 34, y : 70, width: 200, height: 2)) //add the strike line through textfield
label1.backgroundColor = UIColor(patternImage: labelImage!)
self.view.addSubview(label1)
}
Button1 Label1 textfield1 all correspond to the first line of input.
Button2 Label2 textfield2 etc...
The textfields were made using interface builder, the buttons/labels were made programmatically. I was wondering if there is any way (I'm sure there is) to use just one button one label and one textfield to control all user input? The buttons and labels all essentially to the same thing.
Let me know if I'm not too clear.
You can use a TableView with custom cells for your each line. A single cell can be designed with your required Label, TextField and Button. You can make it through the storyboard itself using prototype cell in tableView.
This should really be using a TableView.
That would allow you to set up one row of the table with the elements you want and reuse them the way you are asking about.
You should create a nib file of UITableViewCell class where you can design a single cell with Textfield, label, button. And you should use UITableview on storyboard and after that you should load that nib.

Can't interact with anything inside a UITableViewCell, I'm being blocked by a bool somewhere, where is it?

I'm constantly running into this issue, I don't know how to treat UITableViewCells as UIViews.
I added a button to my UITableViewCell:
let btnWidth = self.contentView.frame.size.width * 1.1
let btnHeight = self.contentView.frame.size.height * 1.6
btnJoinChannel = UIButton(frame: CGRect(x:0,y:0,width:btnWidth,height:btnHeight))
btnJoinChannel.setTitle("Join Channel", for: .normal)
btnJoinChannel.setTitleColor(.white, for: .normal)
btnJoinChannel.backgroundColor = .clear
btnJoinChannel.addTarget(self, action: #selector(JRegionCell.loadRegion), for: .touchUpInside)
self.contentView.addSubview(btnJoinChannel)
Buttons never work on UITableViewCells by default because some kind of touch gesture value overrides the new button.
What do I configure to prevent this override? I would like users to touch buttons inside UITableViewCells. Basically, my cells need to behave like UIViews.
Your button is bigger than content view. Buttons don't work if they are out of superview.

UIScrollView with child UIView (holds content) not detecting taps

I'm hitting a wall. I have a UIScrollView with a child UIView (contentView) which contains the content and a button. The button is not detecting any taps. I've tested many methods, creating the button programmatically, using storyboard, and creating a UITapGestureRecognizer in the contentView... still nothing. From what I understand, UIScrollView does not delegate any touch events to it's children. How do I solve this?
You can create the button programmatically then you add it as a subview for your contentView.
let button = UIButton()
button.frame = CGRectMake(contentView.center.x-20.0, contentView.center.y-20.0, 40.0, 40.0)
button.addTarget(self, action: "handleTap", forControlEvents: UIControlEvents.TouchUpInside)
button.setTitle("Title", forState: UIControlState.Normal)
contentView.addSubview(button)
On the action you can handle the tap
func handleTap() {
//Do whatever you want
print("Button tapped")
}
I tested it using a scrollView and a UIView inside the scrollView

Resources