Add UIButton and UIImage in TableView Section header - ios

I can't figure out what is wrong in this code. i want to display button and image in tableview section header
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let view = UIView()
let image = UIImageView()
image.frame = CGRect(x: view.frame.width - 10 , y: 0, width: 20, height: 20)
image.image = UIImage.init(named: "triangle.png")
let button = UIButton(type: .system)
button.frame = CGRect(x: view.frame.origin.x, y: view.frame.origin.y, width: view.frame.width - 30, height: view.frame.height)
button.setTitle("Open", for: .normal)
button.backgroundColor = .yellow
button.addTarget(self, action: #selector(buttonclick), for: .touchUpInside)
view.addSubview(image)
view.addSubview(button)
return view
}

You shouldn't set imageView and button frame by view frame. Because when viewForHeaderInSection function is being called view frame will be 0.
Instead of view you can use tableview
image.frame = CGRect(x: tableView.frame.width - 20 , y: 0, width: 20, height: 20)
button.frame = CGRect(x: 0, y: 0, width: tableView.frame.width - 30, height: 50)
It is recommended to use autolayout instead of setting frame.

Add below code just after initialising view :
view.frame = CGRect(x: 0 , y: 0, width: tableView.frame.width, height: heightForHeaderInSection)
you forgot to set the view's frame.

Related

Swift button only showing in dark mode

I am adding a button in a tableview section header, and it currently only shows while my phone is in dark mode, I have no idea what the issue might be. All other elements in the header show in both light and dark mode.
headerHeight is a static 200 pixels
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let view = UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.width, height: headerHeight))
let imageButton = UIButton(frame: CGRect(x: view.frame.width / 2 - 50, y: 10, width: 100, height: 100))
imageButton.setImage(UIImage(systemName: "person.crop.circle"), for: .normal)
view.addSubview(imageButton)
let nameButton = UIButton(frame: CGRect(x: 0, y: 110, width: tableView.frame.width, height: 40))
nameButton.tintColor = .label
nameButton.titleLabel?.textColor = .label
nameButton.setTitle("Set Name", for: .normal)
nameButton.titleLabel?.textAlignment = .center
view.addSubview(nameButton)
let accountsLabel = UILabel(frame: CGRect(x: 10, y: 175, width: 80, height: 20))
accountsLabel.text = "Accounts"
accountsLabel.font = UIFont(name: "Helvetica Neue", size: 15)
view.addSubview(accountsLabel)
return view
}
The problem is this line:
nameButton.titleLabel?.textColor = .label
That is not how you set a button's title color. Change it to:
nameButton.setTitleColor(.label, for: .normal)

Swift Add UIView with subviews to titleView

I'd like to customize my navigation bar and insert a UIView with two subviews into the title view of the navigation bar.
Unfortunately the subviews aren't displayed.
Do you have any idea why?
let titleContainer = UIView()
titleContainer.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
let searchIcon = UIButton()
searchIcon.setImage(UIImage(named: "search_icon"), for: UIControlState.normal)
searchIcon.layer.frame = CGRect(x: 0, y: (UIScreen.main.bounds.size.height - 28) / 2, width: 28, height: 28)
titleContainer.addSubview(searchIcon)
let titleLabel = UILabel()
titleLabel.frame = CGRect(x: 28, y: UIScreen.main.bounds.size.height, width: UIScreen.main.bounds.size.width-28, height: UIScreen.main.bounds.size.height)
titleLabel.textColor = UIColor(red:255, green:255, blue:255, alpha:1.0)
titleContainer.addSubview(self.titleLabel)
self.navigationItem.titleView = titleContainer
problem and expected solution:
Why did you use height of all the element as UIScreen.main.bounds.size.height? Please try the below code.
P.S. I have changed the color of searchIcon as i didn't have the image and changed the color of text of label and added some text so that it is visible.
let titleContainer = UIView()
titleContainer.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: 45)
let searchIcon = UIButton()
//searchIcon.setImage(UIImage(named: "search_icon"), for: UIControlState.normal)
searchIcon.backgroundColor = UIColor.red
searchIcon.layer.frame = CGRect(x: 0, y: 8, width: 28, height: 28)
titleContainer.addSubview(searchIcon)
let titleLabel = UILabel()
titleLabel.frame = CGRect(x: 28, y: 8, width: UIScreen.main.bounds.size.width-28, height: 30)
titleLabel.textColor = UIColor.blue//(red:255, green:255, blue:255, alpha:1.0)
titleContainer.addSubview(titleLabel)
titleLabel.text = "Sample Text"
self.navigationItem.titleView = titleContainer
Here is the screenshot of the above code:
Please change the x,y accordingly as per your requirement.
Have you considered making your let bar = UINavigationBar() programmatically and then add it with: self.view.addSubview(bar)?
So you can push all the "UIBarItems" you want..?

How to create a button and segue from titleView image

Having a problem with customizing the navigationBar. I have changed the titleView text to an image through coding. Now I want the image to be a clickable button with a segue to the starting page (for example a home button to the main viewController). How do I make the titleView image into a button (or item) and how do I create a segue from it. I suppose it has to be done in code since I haven't found any other means of doing it. If you have a solution, please be thorough - I'm a beginner.
Simply add a custom UIView containing UIButton and UIImageView to the titleView of navigationItem.
Example:
override func viewDidLoad()
{
super.viewDidLoad()
let button = UIButton(frame: CGRect(x: 0, y: 0, width: self.view.frame.width - 80, height: 30))
button.setTitle("Button", for: .normal)
button.addTarget(self, action: #selector(showMainVC), for: .touchUpInside)
let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width - 80, height: 30))
imageView.image = UIImage(named: "Image")
let customView = UIView(frame: CGRect(x: 0, y: 0, width: self.view.frame.width - 80, height: 30))
customView.addSubview(imageView)
customView.addSubview(button)
self.navigationItem.titleView = customView
}
func showMainVC()
{
//TODO:
}

How to create custom uiview that button can be clicked inside uiview?

I tried to create clicked scrollview button like this (at bottom):
this is my code so far:
scView = UIScrollView(frame: CGRect(x: 0, y: view.frame.maxY-110, width: view.bounds.width, height: 110))
self.view.addSubview(scView)
scView.backgroundColor = UIColor.lightGray
scView.translatesAutoresizingMaskIntoConstraints = false
for i in 0 ... 10 {
let myNewView=UIView(frame: CGRect(x: xOffset, y: CGFloat(buttonPadding), width: 200, height: 100))
myNewView.backgroundColor=UIColor.white
myNewView.layer.cornerRadius=10
self.scView.addSubview(myNewView)
let label = UILabel(frame: CGRect(x: xOffset, y: CGFloat(buttonPadding)+5, width: 150, height: 10))
label.center = CGPoint(x: 160, y: 285)
label.textAlignment = .left
label.text = "I'am a title label"
label.textColor = .black
myNewView.addSubview(label)
let ditancelabel = UILabel(frame: CGRect(x: xOffset, y: CGFloat(buttonPadding)+5, width: 50, height: 10))
ditancelabel.center = CGPoint(x: 160, y: 285)
ditancelabel.textAlignment = .right
ditancelabel.text = "0.04 km"
ditancelabel.textColor = .red
myNewView.addSubview(ditancelabel)
let textView = UITextView(frame: CGRect(x: xOffset, y: CGFloat(buttonPadding)+15, width: 200.0, height: 40.0))
self.automaticallyAdjustsScrollViewInsets = false
textView.center = self.view.center
textView.textAlignment = NSTextAlignment.justified
textView.textColor = UIColor.lightGray
textView.backgroundColor = UIColor.clear
myNewView.addSubview(textView)
let button = UIButton()
button.tag = i
button.backgroundColor = UIColor.white
button.setTitle("\(i)", for: .normal)
button.setTitleColor(.black, for: .normal)
button.backgroundColor = UIColor.clear
button.addTarget(self, action:#selector(handleRegister(sender:)), for: .touchUpInside)
button.frame = CGRect(x: xOffset, y: CGFloat(buttonPadding), width: 200, height: 100)
xOffset = xOffset + CGFloat(buttonPadding) + button.frame.size.width
myNewView.addSubview(button)
}
scView.contentSize = CGSize(width: xOffset, height: scView.frame.height)
but code result like this:
The first button can be clicked, but the other cannot be clicked. And 2 UILabels and 1 UITextView did not appear.
the handleRegister method is to get sender tag and print it as log to know the button can be clicked or not.
How to repair the code so it can be like the custom UIView in the above image?
I need to transfer label and textview text by button click to another viewcontroller which handle by seque in handleRegister.
1) You can't see labels and other control because of your container view size is (200, 100)
let myNewView=UIView(frame: CGRect(x: xOffset, y: CGFloat(buttonPadding), width: 200, height: 100))
and you set center of controls.
label.center = CGPoint(x: 160, y: 285)
ditancelabel.center = CGPoint(x: 160, y: 285)
This center point is not visible within container view. That's why you can't see labels within view. Just comment these line to set center of labels and you can see those perfectly.
2) I need to transfer label and textview text by button click to another viewcontroller which handle by seque in handleRegister.
I hope you have a array in which you stored data to display in your custom view, Just find that object from array based on button tag, and pass that object to another control.
3) The first button can be clicked, but the other cannot be clicked.
Again problem is same like for labels. You had set frame of button like this
button.frame = CGRect(x: xOffset, y: CGFloat(buttonPadding), width: 200, height: 100)
and increase xOffset by this line to create another view
xOffset = xOffset + CGFloat(buttonPadding) + button.frame.size.width
xOffset increased each time with the size of button. So if you print xOffset value it actually print like (assuming initial value of xOffset = 10, padding = 0)
for i in 0 ... 10 {
print(xOffset)
..... your other code
}
Output: will be like
10, 210, 410, 610...... Because of this your button is out of bound from container view and because of that you can't click on that.
I have updated your code, check below
scView = UIScrollView(frame: CGRect(x: 0, y: view.frame.maxY-110, width: view.bounds.width, height: 110))
self.view.addSubview(scView)
scView.backgroundColor = UIColor.lightGray
scView.translatesAutoresizingMaskIntoConstraints = false
for i in 0 ... 10 {
let myNewView=UIView(frame: CGRect(x: xOffset, y: CGFloat(buttonPadding), width: 200, height: 100))
myNewView.backgroundColor=UIColor.white
myNewView.layer.cornerRadius=10
self.scView.addSubview(myNewView)
let subVwOffset = 5
let label = UILabel(frame: CGRect(x: subVwOffset, y: CGFloat(buttonPadding)+5, width: 150, height: 10))
label.textAlignment = .left
label.text = "I'am a title label"
label.textColor = .black
myNewView.addSubview(label)
let ditancelabel = UILabel(frame: CGRect(x: subVwOffset, y: CGFloat(buttonPadding)+5, width: 50, height: 10))
ditancelabel.textAlignment = .right
ditancelabel.text = "0.04 km"
ditancelabel.textColor = .red
myNewView.addSubview(ditancelabel)
let textView = UITextView(frame: CGRect(x: subVwOffset, y: CGFloat(buttonPadding)+15, width: 200.0, height: 40.0))
self.automaticallyAdjustsScrollViewInsets = false
textView.center = self.view.center
textView.textAlignment = NSTextAlignment.justified
textView.textColor = UIColor.lightGray
textView.backgroundColor = UIColor.clear
myNewView.addSubview(textView)
let button = UIButton()
button.tag = i
button.backgroundColor = UIColor.white
button.setTitle("\(i)", for: .normal)
button.setTitleColor(.black, for: .normal)
button.backgroundColor = UIColor.clear
button.addTarget(self, action:#selector(handleRegister(sender:)), for: .touchUpInside)
button.frame = CGRect(x: subVwOffset, y: CGFloat(buttonPadding), width: 200, height: 100)
xOffset = xOffset + CGFloat(buttonPadding) + button.frame.size.width
myNewView.addSubview(button)
}
scView.contentSize = CGSize(width: xOffset, height: scView.frame.height)
Let me know if you find any other difficulty.

Creating a UIButton inside a subView programmatically not working

I'm trying to add a UIButton inside a UIView called containerView. The containerView is showing normally but the UIButton isn't showing up at all. This is my code:
let containerView = UIView()
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
self.containerView.frame = CGRect(x: self.view.frame.size.width - 100, y: 200, width: 225, height: 70)
self.containerView.backgroundColor = UIColor.gray
self.containerView.layer.cornerRadius = 20
self.containerView.clipsToBounds = true
self.view.addSubview(self.containerView)
let button1: UIButton = UIButton()
button1.frame = CGRect(x: self.view.frame.size.width - 70, y: 200, width: 35, height: 35)
button1.clipsToBounds = true
button1.setTitle("Tesing Button", for: .normal)
self.containerView.addSubview(button1)
}
Any help? Thanks!
Your button frame is positioned incorrectly. You have set the value of y as 200 which is beyond the size of your container view.

Resources