How can I add two images (one at the left and one on the right side) in a button in Xcode programaticly? I need also a title of a button - swift

func setupButtonUI() {
if let detailsImage = UIImage(named: "detalji_icon") {
setImage(detailsImage, for: .normal)
contentHorizontalAlignment = .left
contentVerticalAlignment = .center
}
if let arrowImage = UIImage(named: "posalji_zahtev_black_icon") {
setImage(arrowImage, for: .normal)
contentHorizontalAlignment = .right
contentVerticalAlignment = .center
}
}/this is one of the things I tried, but whit this I get only the second image and its set in the center not right and the left image is hot even there/

UIButton has only one imageView, you can create custom button like in this answer
https://stackoverflow.com/a/43112735/13628690

Found the next solution: Made a custom UIView and added two images and label as a subview of customView. Did the constraints programaticly. Just added UITapGestureRecognizer (addGestureRecognizer) at the entire view and its all elements are clickable. The design and functionality are satisfied.

Related

How can I change my custom cell background when pressing a button?

I have a CollectionView and a Button inside of an UIView. The purpose of the button is change the theme of the app, and I can change all colors, except for the backgroundColor of a nameContainerView on my TatodexCell (a custom cell).
I can't figure out how to access that property, and then, change the color I want.
THE FOLLOWING CODE IS LOCATED ON MY TatodexController FILE
My button property is:
let buttonChangeTheme: UIButton? = {
let button = UIButton()
button.setTitle("Change to blue theme", for: .normal)
button.addTarget(self, action: #selector(themeButtonClicked), for: .touchUpInside)
button.titleLabel?.adjustsFontSizeToFitWidth = true
button.layer.borderWidth = 3
button.layer.borderColor = Colors.mainBlack?.cgColor
button.backgroundColor = Colors.darkBlue
button.tintColor = Colors.mainWhite
return button
}()
My button-func is this one:
#objc func themeButtonClicked() {
clickCheck = !clickCheck
if clickCheck {
navigationController?.navigationBar.barTintColor = Colors.lightBlue
collectionViewPokemon?.backgroundColor = Colors.darkBlue
buttonChangeTheme?.backgroundColor = Colors.darkRed
buttonChangeTheme?.setTitle("Return to red theme", for: .normal)
}
else {
navigationController?.navigationBar.barTintColor = Colors.lightRed
collectionViewPokemon?.backgroundColor = Colors.darkRed
buttonChangeTheme?.backgroundColor = Colors.darkBlue
buttonChangeTheme?.setTitle("Change to blue theme", for: .normal)
}
}
THE FOLLOWING CODE IS LOCATED ON MY TatodexCell FILE
The nameContainerView I wanna modify it's bg color is:
lazy var nameContainerView: UIView = {
let nameView = UIView()
nameView.backgroundColor = Colors.lightRed
nameView.addSubview(nameLabel)
nameLabel.center(inView: nameView)
return nameView
}()
My goal is to change nameView.backgroundColor = Colors.lightRed to nameView.backgroundColor = Colors.lightBlue, but I can't access that property.
I would really appreciate any help or advice. Perhaps the solution is hiding in plain sight, but I've tried many ways and none of them worked. Let me know if another chunk of code is needed to be shown.
If you implement the tintColorDidChange() method in your custom collection view cell, and in that method, you set the cell's background color to the tint color, then when you change the owning UICollectionView's tint color, the cells's tintColorDidChange() methods will fire and you'll see the change.

Swift NavBar Hide NavBarItem

Inside of my view controller I have a navBar with an item on the left side and right side. I also have 2 buttons inside of the view controller. I have it so each button does different functionality. I also have the swift file connected to the view.
My issue is that when I do either of the code below inside of my button actions the NavBar Items do not change. I don't know how to remove and add the item back, I also dont understand what Im doing wrong.
self.navigationItem.rightBarButtonItem?.isEnabled = false
self.navigationItem.rightBarButtonItem?.tintColor = UIColor.clear
self.navigationItem.rightBarButtonItem?.isEnabled = true
self.navigationItem.rightBarButtonItem?.tintColor = UIColor.red
Connect Navigation Bar from storyboard to View Controller Class
#IBOutlet var navBar: UINavigationBar!
This will hide Button
navBar.topItem?.rightBarButtonItem?.isEnabled = false
navBar.topItem?.rightBarButtonItem?.tintColor = UIColor.clear
This will show Button
navBar.topItem?.rightBarButtonItem?.isEnabled = true
navBar.topItem?.rightBarButtonItem?.tintColor = UIColor.red
Sorry, i can't make comment due to low reputetion. Which IDE are you using?
The answer of #dharmesh works, if you create the button programmatically:
let btn = UIButton(type: .system)
btn.setTitle("Indietro", for: btn.state)
btn.addTarget(self, action: #selector(annulla), for: .touchUpInside)
self.navigationItem.leftBarButtonItem = UIBarButtonItem(customView: btn)
If you use the one from the IDE it depends on the IDE itself to store the values to hide or change it

Disclosure indicator in tableView cell isn't showing

I have added cell.accessoryType = .disclosureIndicator in my cellForRowAt delegate, and I have also ticked it in the viewController UI options under "accessory". I also added margins to the tableView so that it's 0 in relation to the parent view (that is, the device).
I even set cell.accessoryView?.tintColor = UIColor.black in case something was wrong with the color. But, still, I can't see the little arrow on the right side of the cell. I'm using a default cell. And in other viewControllers that I have it works, but in this one it doesn't.
I checked the width for both the cell and the tableview and they are both 375.
It does work if I add a custom image instead, like this:
let img = UIImage.init(named: "arrow")
cell.accessoryView = UIImageView.init(image: img)
But, I want the standard arrow.
Any more tips on what could be the issue here?
If you're targeting iOS 13 this won't work. You can verify on iOS12 but I've faced this very problem earlier this year and the solution was to add a UIButton to the cell constraining it to the trailing side of the screen.
let disclosureButton = UIButton()
disclosureButton.setImage(UIImage(named: "arrow"), for: .normal)
cell.addSubview(disclosureButton)
disclosureButton.translatesAutoresizingMaskIntoConstraints = false
disclosureButton.trailingAnchor.constraint(equalTo: cell.trailingAnchor, constant: -10).isActive = true
disclosureButton.centerYAnchor.constraint(equalTo: cell.centerYAnchor, constant: 0).isActive = true
disclosureButton.widthAnchor.constraint(equalToConstant: 25).isActive = true
disclosureButton.heightAnchor.constraint(equalToConstant: 25).isActive = true

UITapGestureRecognizer works first time, but not second time

[Greatly simplified]
I'm following a "Let's Build That App" YouTube series on Firebase 3. It's from 2016, so I've had to rework some of the code since Swift has evolved since then, but mostly it's a useful tutorial.
But, I'm stuck on something.
The red box is intended to be a custom titleView with an Image and Name, but I've simplified it to try to find the problem.
viewWillAppear calls setupNavbar which sets up the navbar.titleView:
func setupNavbar() {
let titleView = UIView()
titleView.frame = CGRect(x: 0, y: 0, width: 300, height: 40)
titleView.backgroundColor = .red
let containerView = UIView() // for the Image and Label, later
containerView.translatesAutoresizingMaskIntoConstraints = false
containerView.backgroundColor = .green
// left, top, width, height anchors equal to same for titleView
containerView.leftAnchor.constraint(equalTo: titleView.leftAnchor)
// top, width, height are similar
titleView.addSubview(containerView)
self.navigationItem.titleView = titleView
let recognizer = UITapGestureRecognizer(target: self, action: #selector(showChatController))
titleView.addGestureRecognizer(recognizer)
}
The selector's function is:
#objc func showChatController() {
let chatController = ChatLogTableViewController()
navigationController?.pushViewController(chatController, animated: true)
}
The class ChatLogTableViewController has just the default viewDidLoad().
First, I'm surprised the box is red, and not green. Why is that?
Second, if I click the red box, the ChatController is loaded, as expected. But, when I click "Back" and return to this screen, the red box is not visible, thus I can no longer tap on it. BUT....If I sign out and sign in/up again, the box is red and I can click it again.
What am I missing?
Update 1: The "+" creates a new controller and presents it.
present(UINavigationController(
rootViewController: NewMessageTableViewController()),
animated: true,
completion: nil)
That controller is currently empty, except for a leftBarButtonItem which is just a barButtonSystemItem (.cancel). Just like "Sign Out", this also "resets" the gesture and it works.
Update 2: Code added upon request.
Update 3: question greatly simplified. Also, if I change the showChatController code to just print ("show Chat Controller"), I can click to my heart's content; the red box and its tap gesture both remain.
So, there is something happening when I ...pushViewController and then come back.
Have you tried to set isUserInteractionEnabled property of the label which you set as the navBar's titleView? I know it's silly but I've missed this a lot of times :)
let recognizer = UITapGestureRecognizer(target: self, action: #selector(YourViewController.titleWasTapped))
titleView.isUserInteractionEnabled = true
titleView.addGestureRecognizer(recognizer)
you can try following things:
1. "User Interaction Enabled" in the UILabel Attributes Inspector in the Storyboard.
2. override func viewDidLoad(animated: Bool) {
super.viewDidAppear(animated)
self.titleView.userInteractionEnabled = true
var tapGesture = titleView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(showChatController)))
self.titleView.addGestureRecognizer(tapGesture)
}
func showChatController() {
println("Tap Gesture recognized")
}
Hi #Zonker I've tested your setupNavBar(). It's working fine nothing worng with your code when I press and go back clicking titleView. Reason why you're not getting .green color is you have to give height and width for containerView and big reason is you've put addSubView code below the anchor and there is no .isActive = true in your containerView.leftAnchor.constraint... Please check setupNavBar() code below:
func setupNavbar() {
let titleView = UIView()
titleView.frame = CGRect(x: 0, y: 0, width: 300, height: 40)
titleView.backgroundColor = .red
let containerView = UIView() // for the Image and Label, later
containerView.translatesAutoresizingMaskIntoConstraints = false
containerView.backgroundColor = .green
titleView.addSubview(containerView)
// left, top, width, height anchors equal to same for titleView
containerView.widthAnchor.constraint(equalToConstant: 300).isActive = true
containerView.heightAnchor.constraint(equalToConstant: 40).isActive = true
containerView.leftAnchor.constraint(equalTo: titleView.leftAnchor).isActive = true
// top, width, height are similar
self.navigationItem.titleView = titleView
let recognizer = UITapGestureRecognizer(target: self, action: #selector(showChatController))
titleView.addGestureRecognizer(recognizer)
}
It would better if you push your code in github so we can test your code

How to get Parallax Effect on UIButton in tvOS?

I'm trying to make some UIButtons in a UIView for a tvOS app but have been unable to get them to display the new parallax effect in the simulator. I successfully set up a TV image stack in images.xcassets called "startReadingButton" and my buttons load with the file, but they do not display the shiny parallax effect when swiping around on the remote in the simulator. Here is how I am loading my UIButtons:
for button in 1...5 {
let image = UIImage(named: "startReadingButton")
let newButton = UIButton(type: .Custom)
newButton.frame = buttonRects[button - 1]
newButton.setBackgroundImage(image, forState: UIControlState.Focused)
newButton.imageView?.image = image
newButton.imageView?.adjustsImageWhenAncestorFocused = true
newButton.addTarget(self, action: "buttonPressed:", forControlEvents: UIControlEvents.PrimaryActionTriggered)
newButton.tag = button
newButton.canBecomeFocused()
newButton.adjustsImageWhenHighlighted = true
newButton.clipsToBounds = false
self.addSubview(newButton)
self.homeButtons.append(newButton)
}
So far, I have tried almost every variation I could think of to find a solution, like setting the button type to both .Custom and .System, setting the image in different parameters of the UIButton, etc. However I cannot get the buttons to enter parallax mode and move around when they are focused.
Anyone know what I need to do to get the desired parallax effect?
Solved my problem -
Set your LSR or Apple TV image stack in your UIButton's setImage property for the UIControlState.Focused state.
Set the imageView?.clipsToBounds = false on the UIButton.
Set newButton.imageView?.adjustsImageWhenAncestorFocused = true on the UIButton.
I have got the following code to work as expected:
for button in 1...3 {
let buttonUnpressedTexture = UIImage(contentsOfFile:NSBundle.mainBundle().resourcePath!.stringByAppendingPathComponent("startReadingUnpressed.png"))!
let buttonPressedTexture = UIImage(contentsOfFile:NSBundle.mainBundle().resourcePath!.stringByAppendingPathComponent("startReadingPressed.png"))!
let newButton = UIButton(type: .Custom)
newButton.frame = buttonRects[button - 1]
newButton.setImage(buttonUnpressedTexture, forState: UIControlState.Normal)
newButton.setImage(buttonPressedTexture, forState: UIControlState.Highlighted)
newButton.setImage(UIImage(named: "StartReadingButton"), forState: UIControlState.Focused)
newButton.imageView?.clipsToBounds = false
newButton.imageView?.adjustsImageWhenAncestorFocused = true
newButton.addTarget(self, action: "buttonPressed:", forControlEvents: UIControlEvents.PrimaryActionTriggered)
newButton.tag = button
newButton.canBecomeFocused()
self.addSubview(newButton)
}
"StartReadingButton" is an Apple TV image stack in my images.xcassets catalog.