Anonymous
Проблема с переключением представлений в UIStackView в зависимости от условия
Сообщение
Anonymous » 16 апр 2024, 09:00
В моем проекте iOS я работаю с UIStackView, который содержит несколько подпредставлений. Я хочу динамически переворачивать или перемещать вверх и вниз определенные представления в виде стека в зависимости от условия. В частности,
я пытаюсь манипулировать позициями двух текстовых полей с именами FIRST и SECOND. Однако я столкнулся с проблемой, из-за которой переворачивание работает правильно только при каждом втором касании или щелчке.
Вот мой код для того же
Код: Выделить всё
import UIKit
import Combine
import SnapKit
class ViewController: UIViewController {
private var toggleSubject = PassthroughSubject()
private var toggle = false
private var store = Set()
private lazy var topField: AppTextField = {
let view = AppTextField(title: "First")
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
private lazy var bottomField: AppTextField = {
let view = AppTextField(title: "Second")
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
private lazy var lineView: UIImageView = {
let view = UIImageView(frame: .zero)
view.backgroundColor = .red
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
private lazy var stackView: UIStackView = {
let view = UIStackView(arrangedSubviews: [topField, lineView, bottomField, toggleButton])
view.axis = .vertical
view.spacing = 4.0
view.distribution = .fill
view.alignment = .fill
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
private lazy var toggleButton: UIButton = {
let view = UIButton(frame: .zero)
view.setTitle("Toggle", for: .normal)
view.setTitleColor(.white, for: .normal)
view.setTitleColor(.systemYellow, for: .highlighted)
view.backgroundColor = .darkGray
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
private lazy var selectedTopFieldLabel: UILabel = {
let view = UILabel(frame: .zero)
view.textAlignment = .center
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(stackView)
self.view.addSubview(selectedTopFieldLabel)
toggleSubject.send(toggle)
stackView.snp.makeConstraints { make in
make.leading.trailing.centerY.equalToSuperview().inset(16)
}
lineView.snp.makeConstraints { make in
make.height.equalTo(0.5)
}
selectedTopFieldLabel.snp.makeConstraints { make in
make.top.equalToSuperview().offset(200)
}
toggleButton.addTarget(self, action: #selector(toggleButtonAction), for: .touchUpInside)
toggleSubject.sink { toggle in
print("---> Changed Toggle",toggle)
self.updateUI(toggle: toggle)
UIView.animate(withDuration: 0.25) {
self.stackView.layoutIfNeeded()
}
}.store(in: &store)
self.updateUI(toggle: toggle)
}
@objc func toggleButtonAction() {
toggle.toggle()
toggleSubject.send(toggle)
}
private func updateUI(toggle: Bool) {
let arrangedSubviews = self.stackView.arrangedSubviews
guard var first = arrangedSubviews[0] as? AppTextField,
var second = arrangedSubviews[2] as? AppTextField else {return}
stackView.arrangedSubviews.forEach({$0.removeFromSuperview()})
let changedViews = toggle ? [first, lineView, second, toggleButton] : [second, lineView, first , toggleButton]
guard let firstTextField = changedViews.first as? AppTextField,
let firstfieldPlaceholder = firstTextField.placeholder else {return}
self.selectedTopFieldLabel.text = "Selected On Top " + " -> " + firstfieldPlaceholder
changedViews.forEach { view in
self.stackView.addArrangedSubview(view)
}
// Update constraints
UIView.animate(withDuration: 0.25) {
self.stackView.setNeedsLayout()
self.stackView.layoutIfNeeded()
}
}
}
class AppTextField: UIView {
private lazy var inputField: UITextField = {
let textField = UITextField(frame: .zero)
textField.backgroundColor = .lightGray.withAlphaComponent(0.15)
textField.translatesAutoresizingMaskIntoConstraints = false
return textField
}()
var title: String? {
get { return inputField.placeholder }
set { inputField.placeholder = newValue }
}
var placeholder: String? {
get { return inputField.placeholder }
set { inputField.placeholder = newValue }
}
var text: String? {
get { return inputField.text }
set { inputField.text = newValue }
}
init(title: String) {
super.init(frame: .zero)
self.title = title
setupViews()
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupViews() {
addSubview(inputField)
inputField.snp.makeConstraints { make in
make.edges.equalToSuperview()
make.height.equalTo(48)
}
}
}
Заранее спасибо.
Подробнее здесь:
https://stackoverflow.com/questions/783 ... -condition
1713247244
Anonymous
В моем проекте iOS я работаю с UIStackView, который содержит несколько подпредставлений. Я хочу динамически переворачивать или перемещать вверх и вниз определенные представления в виде стека в зависимости от условия. В частности, я пытаюсь манипулировать позициями двух текстовых полей с именами FIRST и SECOND. Однако я столкнулся с проблемой, из-за которой переворачивание работает правильно только при каждом втором касании или щелчке. Вот мой код для того же [code]import UIKit import Combine import SnapKit class ViewController: UIViewController { private var toggleSubject = PassthroughSubject() private var toggle = false private var store = Set() private lazy var topField: AppTextField = { let view = AppTextField(title: "First") view.translatesAutoresizingMaskIntoConstraints = false return view }() private lazy var bottomField: AppTextField = { let view = AppTextField(title: "Second") view.translatesAutoresizingMaskIntoConstraints = false return view }() private lazy var lineView: UIImageView = { let view = UIImageView(frame: .zero) view.backgroundColor = .red view.translatesAutoresizingMaskIntoConstraints = false return view }() private lazy var stackView: UIStackView = { let view = UIStackView(arrangedSubviews: [topField, lineView, bottomField, toggleButton]) view.axis = .vertical view.spacing = 4.0 view.distribution = .fill view.alignment = .fill view.translatesAutoresizingMaskIntoConstraints = false return view }() private lazy var toggleButton: UIButton = { let view = UIButton(frame: .zero) view.setTitle("Toggle", for: .normal) view.setTitleColor(.white, for: .normal) view.setTitleColor(.systemYellow, for: .highlighted) view.backgroundColor = .darkGray view.translatesAutoresizingMaskIntoConstraints = false return view }() private lazy var selectedTopFieldLabel: UILabel = { let view = UILabel(frame: .zero) view.textAlignment = .center view.translatesAutoresizingMaskIntoConstraints = false return view }() override func viewDidLoad() { super.viewDidLoad() self.view.addSubview(stackView) self.view.addSubview(selectedTopFieldLabel) toggleSubject.send(toggle) stackView.snp.makeConstraints { make in make.leading.trailing.centerY.equalToSuperview().inset(16) } lineView.snp.makeConstraints { make in make.height.equalTo(0.5) } selectedTopFieldLabel.snp.makeConstraints { make in make.top.equalToSuperview().offset(200) } toggleButton.addTarget(self, action: #selector(toggleButtonAction), for: .touchUpInside) toggleSubject.sink { toggle in print("---> Changed Toggle",toggle) self.updateUI(toggle: toggle) UIView.animate(withDuration: 0.25) { self.stackView.layoutIfNeeded() } }.store(in: &store) self.updateUI(toggle: toggle) } @objc func toggleButtonAction() { toggle.toggle() toggleSubject.send(toggle) } private func updateUI(toggle: Bool) { let arrangedSubviews = self.stackView.arrangedSubviews guard var first = arrangedSubviews[0] as? AppTextField, var second = arrangedSubviews[2] as? AppTextField else {return} stackView.arrangedSubviews.forEach({$0.removeFromSuperview()}) let changedViews = toggle ? [first, lineView, second, toggleButton] : [second, lineView, first , toggleButton] guard let firstTextField = changedViews.first as? AppTextField, let firstfieldPlaceholder = firstTextField.placeholder else {return} self.selectedTopFieldLabel.text = "Selected On Top " + " -> " + firstfieldPlaceholder changedViews.forEach { view in self.stackView.addArrangedSubview(view) } // Update constraints UIView.animate(withDuration: 0.25) { self.stackView.setNeedsLayout() self.stackView.layoutIfNeeded() } } } class AppTextField: UIView { private lazy var inputField: UITextField = { let textField = UITextField(frame: .zero) textField.backgroundColor = .lightGray.withAlphaComponent(0.15) textField.translatesAutoresizingMaskIntoConstraints = false return textField }() var title: String? { get { return inputField.placeholder } set { inputField.placeholder = newValue } } var placeholder: String? { get { return inputField.placeholder } set { inputField.placeholder = newValue } } var text: String? { get { return inputField.text } set { inputField.text = newValue } } init(title: String) { super.init(frame: .zero) self.title = title setupViews() } @available(*, unavailable) required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func setupViews() { addSubview(inputField) inputField.snp.makeConstraints { make in make.edges.equalToSuperview() make.height.equalTo(48) } } } [/code] [img]https://i.stack.imgur.com/yispf.gif[/img] Заранее спасибо. Подробнее здесь: [url]https://stackoverflow.com/questions/78328151/issue-with-flipping-views-in-uistackview-based-on-condition[/url]