Динамическое создание кнопок


#1

Добрый день.
Прошу помощи у форумчан с таким вопросом.
Есть массив строковых данных с категориями, который получаем от сервера.
Есть ли какой то способ программно создать кнопку под каждую категорию, причем таким образом, чтобы кнопки располагались рядом друг с другом, до тех пор пока они помещаются в родительский view, в противном случае выстраивались ниже.

На рисунке думаю будет понятно.


Заранее спасибо)


#2

Код не совсем идеальный, но рабочий

override func viewDidLoad() {
    var buttons: [UIButton] = []
        
        for entry in entries {
            buttons.append(createButton(for: entry))
        }
        
        createButtonGrid(withButtons: buttons)
}

func createButton(for entry: String) -> UIButton {
        let button = UIButton(type: .system)
        button.setTitle(entry, for: .normal)
        button.setTitleColor(.black, for: .normal)
        button.titleLabel?.font = UIFont(name: "AvenirNext-Regular", size: 16)
        button.titleLabel?.adjustsFontSizeToFitWidth = true
        button.backgroundColor = UIColor.init(hex: "E8E8EB")
        button.layer.cornerRadius = 19
        button.clipsToBounds = true
        button.addTarget(self, action: #selector(buttonTap), for: .touchUpInside)
        
        var size = button.titleLabel!.text!.size(attributes: [NSFontAttributeName : button.titleLabel!.font!])
        
        if size.width > view.frame.width - 60 {  // padding left + right = 60
            size.width = view.frame.width - 60
        }
        
        button.frame = CGRect(x: 0, y: 0, width: size.width + 40, height: size.height + 20)
        button.contentEdgeInsets = UIEdgeInsetsMake(0, 20, 0, 20)
        
        return button
    }

func createButtonGrid(withButtons buttons: [UIButton], type: Int, completion: () -> ()) {
        let offset: Double = 10
        var x: Double = 0, y: Double = 5, row: Double = 0
        
        let gridFrame = CGRect(x: 0, y: 0, width: view.frame.width, height: 0)
        let grid = UIView(frame: gridFrame )
        
        for idx in 0..<buttons.count {
            let button = buttons[idx]
            
            row += Double(button.frame.width) + offset
            
            if row < Double(gridFrame.width) {
                x = idx == 0 ? offset : row - Double(button.frame.width)
            }
            else {
                x = offset
                row = Double(button.frame.width) + offset
                y += Double(button.frame.height) + offset
            }
            
            let frame = CGRect(x: CGFloat(x), y: CGFloat(y), width: button.frame.width, height: button.frame.height)
            button.frame = frame
            
            grid.addSubview(button)
            grid.frame.size.height = CGFloat(y) + button.frame.height
        }

        view.addSubview(grid)
}

#3

#4

Или так можно https://yadi.sk/d/YbIQF7ZfYi8P3w


#5

Спасибо огромное за помощь, все получилось =))
Но теперь не могу понять как сделать отступы. Пробовал и frame менять и UILabel в UIView добавлять, по всякому пробовал в общем, но результат всегда один и тот же

Подскажи пожалуйста


#6

Все, допер, не там менял =)))) спасибо еще раз


#7

Привет, как не печально, я наткнулся на туже проблему ) Не подскажешь как ты смог реализовать данные кнопки ? Буду очень благодарен.


#8

Используйте либу выше, она еще доступна.
Либо поищите реализацию через CollectionView, должно быть много разных.