Creating dynamic multiple UIButton programmatically - swift

I am creating my UI programmatically, and this is how I create a button
let button: UIButton = {
let button = UIButton()
button.setTitle("Try1",.normal)
return button
}
And this is what I want to do. For example movie1 has got 2 categories, Dram & Horror I just want to show 2 of them.
Movie2 has got 4 categories, Dram&Horror&Sport& War i just want to show 4 of them.
And now Im stuck I have NO idea what to do. I know you guys gonna give minus rep but I need help.
Done! Solution is below
First I have made a struct
struct Category {
let title: String
let color: UIColor
init(title: String, color: UIColor) {
self.title = title
self.color = color
}
}
Then I made an empty array type of Category Struct
var categories = [Category]()
/* I appended some stuff manually to this array */
categories.append(Category(title: "Dram", color: Colors.cherry))
categories.append(Category(title: "Sport", color: Colors.lightGreen))
categories.append(Category(title: "Horror", color: Colors.purple))
categories.append(Category(title: "War", color: Colors.darkBlue))
/* Then I made a for loop */
for category in categories{
let button = UIButton()
button.createButton(title: category.title, titleColor: .white, fontType: "bold", fontSize: 17, background: category.color, cornerRadius: 4)
stackView.addArrangedSubview(button)
}

Use Horizontal StackView for that. In StackView you can add as much arranged subviews as you want and it will be automatically adjusting to the available space. Just setup constraints for StackView and rest will just work out of the box.
You can add your button to StackView using:
stackView.addArangedSubview(button)
To create button you can simple use for loop:
for i in 1...3 { //change 3 to your value
let button = UIButton()
stackView.addArangedSubview(button)
}

If you want to create multiple buttons in horizontal then add button in scrollview
Swift 4.0
func ButtonCreation() {
yourScrollviewname.isScrollEnabled = true
yourScrollviewname.isUserInteractionEnabled = true
let numberOfButtons = 16
let numberofRows = 1
var count = 0
var px = 0
var py = 0
for _ in 1...numberofRows {
px = 0
if count < numberOfButtons {
for j in 1...numberOfButtons{
count += 1
let Button = UIButton()
Button.tag = count
Button.frame = CGRect(x: px, y: 0, width: 80, height: 27)
Button.layer.borderWidth = 1.0
Button.layer.masksToBounds = true
Button.setTitleColor(UIColor.black, for: .normal)
print(colorArr[j-1])
Button.setTitle(colorText[j-1], for: .normal)
Button.addTarget(self, action: #selector(scrollButtonAction), for: .touchUpInside)
yourScrollviewname.addSubview(Button)
px = px + Int(yourScrollviewname.frame.width)/2 - 50
}
}else{
for j in numberOfButtons/2...numberOfButtons {
count += 1
let Button = UIButton()
Button.tag = count
Button.frame = CGRect(x: px+10, y: py+10, width: 80, height: 427)
Button.backgroundColor = UIColor.black
Button.setTitle("Hello \(j) ", for: .normal)
Button.addTarget(self, action: #selector(scrollButtonAction), for: .touchUpInside)
yourScrollviewname.addSubview(Button)
px = px + Int(yourScrollviewname.frame.width)/2 - 30
}
}
py = Int(yourScrollviewname.frame.height)-70
}
yourScrollviewname.contentSize = CGSize(width: px, height: py)
}

Swift 3.0 ...
let stackview = UIStackView(frame: CGRect(x: 0, y: 0, width: 512, height: 356)) // set your postion
stackview.axis = . Horizontal
stackview.spacing = 10.0
stackview.alignment = .Fill
stackview.distribution = .EqualSpacing
for i in 1...3 {
let button = UIButton()
stackview.addArangedSubview(button)
}

Related

Why does the selector, #objc, function add a subview, of my button image (as a UIImageView), in my UIButton?

I first declare the button
let balloon = UIButton()
A background image then gets added to the balloon
balloon.setBackgroundImage(UIImage(named:"balloon.jpg"), for: .normal)
An image view of the points get added to the balloon as a subview
subView = UIImageView(image: UIImage(named: "1") )
subView.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
subView.contentMode = UIView.ContentMode.scaleAspectFit
subView.center = CGPoint(x: balloon.frame.width/2, y: balloon.frame.height/2)
balloon.addSubview(subView)
I then use the addTarget function for the balloon
balloon.addTarget(self, action: #selector(pop), for: .touchUpInside)
After pop gets called (when the user taps on the balloon), the balloon now contains 2 subviews
- At index 0 of balloon.subviews, there is a UIImageView that is essentially the picture of the balloon with the same dimensions as the balloon button
- And the subs view that I added (aka the points)
here is how I found this problem in my addTarget function (pop):
#objc func pop(_ balloon: UIButton){
print("4.This is the balloon after calling pop \(balloon)")
print("5. This is the subview of the balloon after calling pop \(balloon.subviews)")
Ive added print statements in my function that verifies that the balloons are the same in both the pop func and my balloon creation func
I have already looked at the documentation for both UIButton and addTarget and neither of them have specified why the background image of the button gets created as a subview of the button when the selector func gets called
There shouldn't be that extra UIImageView in my UIButton since I never added that
What you're seeing has nothing to do with your selector / #objc func...
Many UIKit classes do a lot of "under-the-hood" work.
In the case of UIButton, subviews are only added as-needed.
For example, if this is all the code you execute:
let balloon = UIButton()
balloon.frame = CGRect(x: 100, y: 200, width: 240, height: 100)
view.addSubview(balloon)
The resulting button has Zero subviews.
If we do this:
let balloon = UIButton()
balloon.frame = CGRect(x: 100, y: 200, width: 240, height: 100)
view.addSubview(balloon)
balloon.setTitle("ABC", for: [])
The resulting button now has 1 subviews.
let balloon = UIButton()
balloon.frame = CGRect(x: 100, y: 200, width: 240, height: 100)
view.addSubview(balloon)
balloon.setTitle("ABC", for: [])
balloon.setBackgroundImage(img, for: .normal)
The resulting button now has 2 subviews.
let balloon = UIButton()
balloon.frame = CGRect(x: 100, y: 200, width: 240, height: 100)
view.addSubview(balloon)
balloon.setTitle("ABC", for: [])
balloon.setBackgroundImage(imgA, for: .normal)
balloon.addSubview(subview)
The resulting button now has 3 subviews.
let balloon = UIButton()
balloon.frame = CGRect(x: 100, y: 200, width: 240, height: 100)
view.addSubview(balloon)
balloon.setTitle("ABC", for: [])
balloon.setBackgroundImage(imgA, for: .normal)
balloon.addSubview(subview)
balloon.setImage(imgB, for: [])
And now we have 4 subviews.
Apple strongly discourages messing with the internals of UIButton. You might be better off creating a view subclass that contains a button and any additional subviews, rather than your current approach.
Worth Noting
the subviews may not be added until they are needed. So, if you set the title or image or background image in viewDidLoad(), those subviews will not be created until viewDidLayoutSubviews ... or even until the button is actually rendered.
the title label may be created even when you don't expect it to. For example, if the only thing you do to the button is constrain its position, it will get a title label. However, if you set the background image, the title label will be omitted.
Here is a quick example to demonstrate some of the resulting subview counts:
class BtnVC: UIViewController {
var buttons: [UIButton] = []
let stack = UIStackView()
let infoLabel: UILabel = {
let v = UILabel()
v.numberOfLines = 0
v.font = .monospacedSystemFont(ofSize: 14, weight: .regular)
return v
}()
var didLoadStr: String = ""
var didLayoutStr: String = ""
var didAppearStr: String = ""
override func viewDidLoad() {
super.viewDidLoad()
let largeFont = UIFont.systemFont(ofSize: 32)
let configuration = UIImage.SymbolConfiguration(font: largeFont) // <1>
guard let img2 = UIImage(systemName: "02.circle.fill", withConfiguration: configuration),
let img3 = UIImage(systemName: "03.circle.fill"),
let img4 = UIImage(systemName: "04.circle.fill")
else {
return
}
var b: UIButton!
b = UIButton()
buttons.append(b)
b = UIButton()
b.setTitle("1", for: [])
buttons.append(b)
b = UIButton()
b.setTitle("1", for: [])
b.setImage(img2, for: [])
buttons.append(b)
b = UIButton()
b.setTitle("1", for: [])
b.setImage(img2, for: [])
b.setBackgroundImage(img3.withTintColor(.systemGreen, renderingMode: .alwaysOriginal), for: [])
buttons.append(b)
b = UIButton()
b.setTitle("1", for: [])
b.setImage(img2, for: [])
b.setBackgroundImage(img3.withTintColor(.systemGreen, renderingMode: .alwaysOriginal), for: [])
let v = UIImageView(image: img4)
v.tintColor = .systemRed
v.frame = CGRect(x: 0, y: 0, width: 32, height: 32)
b.addSubview(v)
buttons.append(b)
stack.axis = .vertical
stack.spacing = 8
stack.distribution = .fillEqually
stack.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(stack)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
stack.topAnchor.constraint(equalTo: g.topAnchor, constant: 120.0),
stack.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
stack.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
stack.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: -20.0),
])
// add this first button *without* auto-layout
buttons[0].frame = CGRect(x: 80, y: 40, width: 200, height: 50)
view.addSubview(buttons[0])
// add the rest of the buttons to the stack view
buttons.forEach { v in
v.backgroundColor = .systemYellow
v.setTitleColor(.black, for: [])
if v != buttons.first {
stack.addArrangedSubview(v)
}
}
stack.addArrangedSubview(infoLabel)
var s = "didLoad : "
buttons.forEach { v in
s += "\(v.subviews.count) / "
}
didLoadStr += s + "\n"
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
// first button is not using auto-layout constraints, so
// let's size it to match the buttons in the stack view
// and posiiton it 8-pts above the stack view
var r = buttons[1].bounds
r.origin.y = stack.frame.origin.y - r.height - 8.0
r.origin.x = stack.frame.origin.x
buttons[0].frame = r
var s = "didLayout: "
buttons.forEach { v in
s += "\(v.subviews.count) / "
}
didLayoutStr += s + "\n"
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
var s = "didAppear: "
buttons.forEach { v in
s += "\(v.subviews.count) / "
}
didAppearStr += s + "\n"
infoLabel.text = didLoadStr + didLayoutStr + didAppearStr
}
}
That code will create 5 buttons, with each successive button getting another subview - title, image, backgroundImage, addSubview - and the "Info Label" at the bottom will show the subviews count at each stage (as is often the case, didLayoutSubviews() is called more than once):

One UI element for all VC [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
How I can create Custom view element with animation like a separate class for all view controllers, so that not write this element each time for each VC.
For example:
I am want create bottom view with button and if I am press on button animation will be appeared, and I am can do different action for different VC.
How I can create this view with animation one time for all VC and implement different action inside VC?
I can only create it each time for each VC, all work done but it's terrible code and sometimes may be hard for maintenance.
This it example how I am create my bottom menu and this way looking good but how work.
import Foundation
import UIKit
class BottomMenu: UIViewController {
static let shared = BottomMenu()
var yPosBottomUIView: CGFloat = 90.0
var yPosCenterButton: CGFloat = 35
var yPosBackButton: CGFloat = 35
var yPosForwardButton: CGFloat = 35
var yPosContextMenu: CGFloat = 35
var yPosUpdateButton: CGFloat = 35
var backButtonEnable: Bool = false
var forwardButtonEnable: Bool = false
lazy var image: UIImageView = {
let image = UIImageView(frame: CGRect(x: 0, y: UIScreen.main.bounds.maxY - yPosBottomUIView, width: UIScreen.main.bounds.width, height: 90))
if (osTheme == .dark) {
DispatchQueue.main.async {
image.image = UIImage(named: "SurfaceBlack")
}
return image
} else {
DispatchQueue.main.async {
image.image = UIImage(named: "SurfaceLight")
}
return image
}
}()
lazy var centerButton: UIButton = {
let button = UIButton(frame: CGRect(x: (UIScreen.main.bounds.maxX / 2) - 25, y: (UIScreen.main.bounds.maxY - 50) - yPosCenterButton, width: 50, height: 50))
if (osTheme == .dark) {
button.backgroundColor = UIColor(red: 0.118, green: 0.118, blue: 0.15, alpha: 1)
} else {
button.backgroundColor = UIColor(red: 0.118, green: 0.118, blue: 0.15, alpha: 1)
}
button.layer.cornerRadius = 25
button.setImage(UIImage(named: "Menu"), for: .normal)
button.addTarget(self, action: #selector(centralButtonAction), for: .touchUpInside)
button.isEnabled = false
return button
}()
lazy var backButton: UIButton = {
let button = UIButton(frame: CGRect(x: (UIScreen.main.bounds.minX) + 25, y: (UIScreen.main.bounds.maxY - 15.5) - yPosBackButton, width: 36, height: 36))
button.backgroundColor = .clear
button.setImage(UIImage(named: "whiteBackArrow"), for: .normal)
button.addTarget(self, action: #selector(centralButtonAction), for: .touchUpInside)
button.isEnabled = backButtonEnable
return button
}()
lazy var forwardButton: UIButton = {
let button = UIButton(frame: CGRect(x: (UIScreen.main.bounds.minX) + 90, y: (UIScreen.main.bounds.maxY - 15.5) - yPosForwardButton, width: 36, height: 36))
button.backgroundColor = .clear
button.setImage(UIImage(named: "whiteBackArrow"), for: .normal)
button.imageView?.transform = CGAffineTransform(rotationAngle: CGFloat.pi)
button.addTarget(self, action: #selector(centralButtonAction), for: .touchUpInside)
button.isEnabled = forwardButtonEnable
return button
}()
lazy var contextMenu: UIButton = {
let button = UIButton(frame: CGRect(x: (UIScreen.main.bounds.maxX) - 60, y: (UIScreen.main.bounds.maxY - 15.5) - yPosContextMenu, width: 36, height: 36))
button.backgroundColor = .clear
button.setImage(UIImage(named: "ContextMenu"), for: .normal)
button.addTarget(self, action: #selector(contextMenuButtonAction), for: .touchUpInside)
return button
}()
lazy var updateButton: UIButton = {
let button = UIButton(frame: CGRect(x: (UIScreen.main.bounds.maxX) - 125, y: (UIScreen.main.bounds.maxY - 15.5) - yPosUpdateButton, width: 36, height: 36))
button.backgroundColor = .clear
button.setImage(UIImage(named: "updateN"), for: .normal)
button.addTarget(self, action: #selector(centralButtonAction), for: .touchUpInside)
button.isEnabled = false
return button
}()
lazy var blur: UIVisualEffectView = {
let blurEffectView = UIVisualEffectView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
let blurEffect = UIBlurEffect(style: .dark)
blurEffectView.effect = blurEffect
blurEffectView.alpha = 0
return blurEffectView
}()
#objc func centralButtonAction(_ sender: UIButton?) {
print("Center Tapped")
}
#objc func contextMenuButtonAction(_ sender: UIButton?) {
print("Context Menu Tapped")
// IF I am past blur effect here and some action for diffent VC nothing happens but each time I'll saw printed text above)
}
}
This is image of menu which I am create but I am write code each time for each VC
Menu have ... when I press on it I am show the same animation for all VC and add some others view BUT When I am closed others sub view I am want implement different action depend of VC where menu did be opened.
Did you tried making one controller as base controller that can be inherited by all child controller and the common actions/activites to be part of that controller. Or maybe using a container view for child controller so that you can inherit properties of your base controller to your child controller.It depends on whatever suits your actual requirements

How do I prevent one UIView from being hidden by another UIView?

I'm creating a custom, reusable segmented controller using UIViews and I'm having a problem with overlapping views. It currently looks like this:
You can see that the blue selector is under the buttons but I want it to sit at the bottom and be four pixels high. To do this, I have:
let numberOfButtons = CGFloat(buttonTitles.count)
let selectorWidth = frame.width / numberOfButtons
let selectorYPosition = frame.height - 3 <--- This cause it to be hidden behind the button
selector = UIView(frame: CGRect(x: 0, y: selectorYPosition, width: selectorWidth, height: 4))
selector.layer.cornerRadius = 0
selector.backgroundColor = selectorColor
addSubview(selector)
bringSubviewToFront(selector) <--- I thought this would work but it does nothing
which results in the selector UIView being hidden behind the segment UIView (I have the Y position set to - 3 so you can see how it's being covered up. I actually want it to be - 4, but that makes it disappear entirely):
I thought using bringSubviewToFront() would bring it in front of the segment UIView but it doesn't seem to do anything. I've looked through Apple View Programming Guide and lots of SO threads but can't find an answer.
Can anybody help me see what I'm missing?
Full code:
class CustomSegmentedControl: UIControl {
var buttons = [UIButton]()
var selector: UIView!
var selectedButtonIndex = 0
var borderWidth: CGFloat = 0 {
didSet {
layer.borderWidth = borderWidth
}
}
var borderColor: UIColor = UIColor.black {
didSet {
layer.borderColor = borderColor.cgColor
}
}
var separatorBorderColor: UIColor = UIColor.lightGray {
didSet {
}
}
var commaSeparatedTitles: String = "" {
didSet {
updateView()
}
}
var textColor: UIColor = .lightGray {
didSet {
updateView()
}
}
var selectorColor: UIColor = .blue {
didSet {
updateView()
}
}
var selectorTextColor: UIColor = .black {
didSet {
updateView()
}
}
func updateView() {
buttons.removeAll()
subviews.forEach { $0.removeFromSuperview() }
// create buttons
let buttonTitles = commaSeparatedTitles.components(separatedBy: ",")
for buttonTitle in buttonTitles {
let button = UIButton(type: .system)
button.setTitle(buttonTitle, for: .normal)
button.setTitleColor(textColor, for: .normal)
button.backgroundColor = UIColor.white
button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
buttons.append(button)
}
// make first button selected
buttons[0].setTitleColor(selectorTextColor, for: .normal)
let numberOfButtons = CGFloat(buttonTitles.count)
let selectorWidth = frame.width / numberOfButtons
let selectorYPosition = frame.height - 3
selector = UIView(frame: CGRect(x: 0, y: selectorYPosition, width: selectorWidth, height: 4))
selector.layer.cornerRadius = 0
selector.backgroundColor = selectorColor
addSubview(selector)
bringSubviewToFront(selector)
let stackView = UIStackView(arrangedSubviews: buttons)
stackView.axis = .horizontal
stackView.alignment = .fill
stackView.distribution = .fillEqually
addSubview(stackView)
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
stackView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
stackView.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
stackView.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
}
#objc func buttonTapped(button: UIButton) {
for (buttonIndex, btn) in buttons.enumerated() {
btn.setTitleColor(textColor, for: .normal)
if btn == button {
let numberOfButtons = CGFloat(buttons.count)
let selectorStartPosition = frame.width / numberOfButtons * CGFloat(buttonIndex)
UIView.animate(withDuration: 0.3, animations: { self.selector.frame.origin.x = selectorStartPosition })
btn.setTitleColor(selectorTextColor, for: .normal)
}
}
sendActions(for: .valueChanged)
}
}
You are covering up your selector with the stackView.
You need to do:
bringSubviewToFront(selector)
after you have added all of the views. Move that line to the bottom of updateView().

resolving the issue coming with text field and button image issue

I am new in swift.I have created simple login screen .I have two issues coming with loginviewController.swift
Issue 1 # i dont know how to compare the two image that is displayed in button . I have used if checkbox.setImage(img, for: .normal) for comparing image that is displayed in side button for toggle action between checked and unchecked
let img = UIImage(named:"check box#1x.png")
let img2 = UIImage(named:"uncheck box.png")
#IBOutlet weak var checkbox: UIButton!
#IBAction func checkbox(_ sender: Any) {
if checkbox.setImage(img, for: .normal)
{
checkbox.setImage(img , for: .normal)
}
else{
checkbox.setImage(img2, for: .normal)
}
}
Issue 2 # I am trying to high light the bottom borders of text field .i am writing the code for highlighting two text field but it is highlighting only single text field
func boaderSetting() {
let border = CALayer()
let width = CGFloat(1.0)
border.borderColor = UIColor.orange.cgColor
border.frame = CGRect(x: 0, y: username_input.frame.size.height - width, width: username_input.frame.size.width, height: username_input.frame.size.height)
border.borderWidth = width
username_input.layer.addSublayer(border)
username_input.layer.masksToBounds = true
///
let border1 = CALayer()
let width1 = CGFloat(1.0)
border1.borderColor = UIColor.orange.cgColor
border1.frame = CGRect(x: 0, y: password_input.frame.size.height - width1, width: password_input.frame.size.width, height: password_input.frame.size.height)
border1.borderWidth = width1
password_input.layer.addSublayer(border)
password_input.layer.masksToBounds = true
}
how to
->compare image displayed in button with other image
-> hight light the bottom border of both text field .
you can download the project from this link https://drive.google.com/file/d/1zjNUBXZ-9WL4DTglhMXIlN-TpaO5IXBz/view?usp=sharing
To check against an image in the button you can use button.currentImage == image. In your example it will look like this
#IBAction func checkbox(_ sender: Any) {
if checkbox.currentImage == img2 {
checkbox.setImage(img , for: .normal)
} else {
checkbox.setImage(img2, for: .normal)
}
}
It is only showing a highlight on the bottom text field border as there is a mistake in your example here password_input.layer.addSublayer(border), you want to use border1 here instead.
func boaderSetting() {
let border = CALayer()
let width = CGFloat(1.0)
border.borderColor = UIColor.orange.cgColor
border.frame = CGRect(x: 0, y: username_input.frame.size.height - width, width: username_input.frame.size.width, height: username_input.frame.size.height)
border.borderWidth = width
username_input.layer.addSublayer(border)
username_input.layer.masksToBounds = true
///
let border1 = CALayer()
let width1 = CGFloat(1.0)
border1.borderColor = UIColor.orange.cgColor
border1.frame = CGRect(x: 0, y: password_input.frame.size.height - width1, width: password_input.frame.size.width, height: password_input.frame.size.height)
border1.borderWidth = width1
password_input.layer.addSublayer(border1)
password_input.layer.masksToBounds = true
}
For #1 you can simply set images for different states.
button.setImage(UIImage(named: "imageForSelected"), for : .selected)
button.setImage(UIImage(named: "imageForNotSelected"), for : .normal)
And then somewhere in your logic set button state
button.setSelected(true)

Accessing to UIView contents of a UIScrollView in Swift

I have a function that creates an scrollview "personsScrollView".
#IBOutlet var personsScrollView: UIScrollView!
var personsScroll = UIView()
personsScroll = createPersonsScroll(CGSizeMake(60.0, 80.0), avatarCount: 10)
func createPersonsScroll(buttonSize:CGSize, avatarCount:Int) -> UIView {
let padding = CGSizeMake(10, 10)
let personButtonView = UIView()
var buttonPosition = CGPointMake(padding.width * 0.5, padding.height)
let buttonIncrement = buttonSize.width + padding.width
personButtonView.frame.origin = CGPointMake(0,0)
personButtonView.frame.size.width = (buttonSize.width + padding.width) * CGFloat(avatarCount+1)
personButtonView.frame.size.height = (buttonSize.height + 2.0 * padding.height)
for i in 0...(avatarCount-1) {
let button = UIButton(type: .Custom)
button.tag = i
button.frame.size = CGSize(width: 60, height: 55)
button.frame.origin.x = buttonPosition.x
button.imageView?.contentMode = UIViewContentMode.ScaleAspectFit
button.setImage(UIImage(named: self.person[button.tag].avatar), forState: .Normal)
button.addTarget(self, action: "addPersonSelected:", forControlEvents: .TouchUpInside)
buttonPosition.x = buttonPosition.x + buttonIncrement
let label = UILabel(frame: CGRectMake(0, 60, 60, 15))
label.text = self.person[i].name
button.addSubview(label)
personButtonView.addSubview(button)
}
}
personsScrollView.contentSize = personButtonView.frame.size
personsScrollView.addSubview(personButtonView)
return personButtonView
}
This function creates a UIView "personButtonView" that will contain the 10 UIbuttons "button", and each button has a different image.
My questions is, outside of the code, in ViewDidLoad(), how do I access for example to the image of the 2nd button to replace only that image? Or how to access to the label of the 4th button to change its text?
I would appreciate your help!
Thanks in advance!
Looking at this code, a hierarchy of views and subviews is being created. If you want a clean way to access these then you can simply create UIView subclasses to encapsulate your content.
To do this, refactor your code in createPersonsScroll into initializers. I can see several UIButton views being created, so you can define an AvatarButton class to encapsulate those, and probably also a PersonView class for its parent, with a property to access its content.
The idea is that you could then replace
personsScroll = createPersonsScroll(buttonSize: CGSizeMake(60.0, 80.0), avatarCount: 10)
with for example:
personView = PersonView(CGSizeMake(60.0, 80.0), avatarCount: 10)
// ...
personView.avatarButtons[2].image = myImage
personView.avatarButtons[4].text = myString