Поскольку я интегрирую собственный экран iOS в плагин Flutter, мне приходится программно устанавливать ограничения для пользовательского интерфейса, поскольку раскадровки нет.
У меня есть эти компоненты пользовательского интерфейса:
var overlayMaskView: UIView = UIView()
var previewView: UIView = UIView()
var stillImagePreviewView: UIImageView = UIImageView()
var viewFinderShapeLabel: UILabel = UILabel()
var viewfinderShapeType: UISegmentedControl = UISegmentedControl()
var vehicleTypeLabel: UILabel = UILabel()
var vehicleType: UISegmentedControl = UISegmentedControl()
Я читаю их ограничения из раскадровки, но изо всех сил пытаюсь воспроизвести их программно.
Мне удалось установить ограничения для overlayMaskView
, previewView
и stillImagePreviewView
четырех привязок к привязкам безопасной области.
// view.translatesAutoresizingMaskIntoConstraints = false
previewView.translatesAutoresizingMaskIntoConstraints = false
previewView.backgroundColor = UIColor.black//.black
previewView.contentMode = .scaleToFill
previewView.isUserInteractionEnabled = true
previewView.isOpaque = true
previewView.clearsContextBeforeDrawing = true
previewView.clipsToBounds = false
previewView.autoresizesSubviews = true
view.addSubview(previewView)
previewView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 0).isActive = true
previewView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: 0).isActive = true
previewView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 0).isActive = true
previewView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 0).isActive = true
stillImagePreviewView.translatesAutoresizingMaskIntoConstraints = false
stillImagePreviewView.contentMode = .scaleAspectFit
stillImagePreviewView.isUserInteractionEnabled = false
stillImagePreviewView.isOpaque = true
stillImagePreviewView.clearsContextBeforeDrawing = true
stillImagePreviewView.clipsToBounds = true
stillImagePreviewView.autoresizesSubviews = true
view.addSubview(stillImagePreviewView)
stillImagePreviewView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 0).isActive = true
stillImagePreviewView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: 0).isActive = true
stillImagePreviewView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 0).isActive = true
stillImagePreviewView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 0).isActive = true
overlayMaskView.translatesAutoresizingMaskIntoConstraints = false
overlayMaskView.contentMode = .scaleToFill
overlayMaskView.isUserInteractionEnabled = true
overlayMaskView.isOpaque = true
overlayMaskView.clearsContextBeforeDrawing = true
overlayMaskView.clipsToBounds = false
overlayMaskView.autoresizesSubviews = true
view.addSubview(overlayMaskView)
overlayMaskView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 0).isActive = true
overlayMaskView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: 0).isActive = true
overlayMaskView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 0).isActive = true
overlayMaskView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 0).isActive = true
Затем первая метка viewFinderShapeLabel
, центр которой x выровнен по оси x вида, верхняя привязка к верхней привязке безопасной области с константой 8, ведущие и конечные привязки к ведущей и завершающей привязке безопасной области с константой 16.
Итак, я установил их все так, и они оказались в нужном положении:
viewFinderShapeLabel.translatesAutoresizingMaskIntoConstraints = false
viewFinderShapeLabel.text = "Formato targa"
viewFinderShapeLabel.textAlignment = .center
viewFinderShapeLabel.textColor = UIColor.white
viewFinderShapeLabel.isEnabled = true
viewFinderShapeLabel.isUserInteractionEnabled = false
viewFinderShapeLabel.isOpaque = false
viewFinderShapeLabel.clearsContextBeforeDrawing = true
viewFinderShapeLabel.autoresizesSubviews = true
view.addSubview(viewFinderShapeLabel)
viewFinderShapeLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0).isActive = true
viewFinderShapeLabel.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 8).isActive = true
viewFinderShapeLabel.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 16).isActive = true
viewFinderShapeLabel.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -16).isActive = true
Затем есть первый сегментированный контроллер, у которого центр x также выровнен по оси x представления, ведущие и конечные привязки к ведущей и конечной привязкам безопасной области с константой 16, а его верхняя привязка к нижней привязке viewFinderShapeLabel с константой 8.
viewfinderShapeType.translatesAutoresizingMaskIntoConstraints = false
viewfinderShapeType = UISegmentedControl(items: ["RETTANGOLARE", "QUADRATA"])
viewfinderShapeType.setEnabled(true, forSegmentAt: 0)
viewfinderShapeType.setEnabled(true, forSegmentAt: 1)
viewfinderShapeType.selectedSegmentIndex = 0
viewfinderShapeType.isEnabled = true
viewfinderShapeType.isUserInteractionEnabled = true
viewfinderShapeType.clearsContextBeforeDrawing = true
viewfinderShapeType.autoresizesSubviews = true
view.addSubview(viewfinderShapeType)
viewfinderShapeType.centerXAnchor.constraint(equalTo: view.centerXAnchor, constant: 0).isActive = true
viewfinderShapeType.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 16).isActive = true
viewfinderShapeType.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -16).isActive = true
viewfinderShapeType.topAnchor.constraint(equalTo: viewFinderShapeLabel.bottomAnchor, constant: 8).isActive = true
Эта настройка не удалась, поскольку сегментированный элемент управления размещается в верхнем левом углу без каких-либо интервалов.
Что я делаю неправильно, из-за чего эти последние ограничения не работают?
Привет, @Paulw11, давно я не задавал вопрос, связанный со Swift. Действительно, использование трех ограничений излишне, я знаю, на самом деле я буду использовать только конечные и ведущие.
@Фабио, я собирался спросить тебя о твоем ответе, но он был удален??
Я не совсем понимаю, как вы хотите создать пользовательский интерфейс... Ниже приведен пример, основанный на вашем коде, который может вам помочь, часть, которая меняет цвет, уже является imageView:
import UIKit
var overlayMaskView = UIView()
var previewView = UIView()
var stillImagePreviewView = UIImageView()
var viewFinderShapeLabel = UILabel()
var viewfinderShapeType = UISegmentedControl()
var vehicleTypeLabel = UILabel()
var vehicleType = UISegmentedControl()
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .black
previewView.translatesAutoresizingMaskIntoConstraints = false
previewView.backgroundColor = UIColor.red //.black
view.addSubview(previewView)
previewView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
previewView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
previewView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
previewView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
viewFinderShapeLabel.translatesAutoresizingMaskIntoConstraints = false
viewFinderShapeLabel.text = "Formato targa"
viewFinderShapeLabel.font = .systemFont(ofSize: 16, weight: .bold)
viewFinderShapeLabel.textAlignment = .center
viewFinderShapeLabel.textColor = .white
previewView.addSubview(viewFinderShapeLabel)
viewFinderShapeLabel.heightAnchor.constraint(equalToConstant: 30).isActive = true
viewFinderShapeLabel.topAnchor.constraint(equalTo: previewView.topAnchor, constant: 16).isActive = true
viewFinderShapeLabel.leadingAnchor.constraint(equalTo: previewView.leadingAnchor, constant: 16).isActive = true
viewFinderShapeLabel.trailingAnchor.constraint(equalTo: previewView.trailingAnchor, constant: -16).isActive = true
let items = ["RETTANGOLARE", "QUADRATA"]
viewfinderShapeType = UISegmentedControl(items: items)
viewfinderShapeType.selectedSegmentIndex = 0
viewfinderShapeType.layer.cornerRadius = 5.0
viewfinderShapeType.backgroundColor = .white.withAlphaComponent(0.5)
viewfinderShapeType.addTarget(self, action: #selector(change), for: .valueChanged)
viewfinderShapeType.translatesAutoresizingMaskIntoConstraints = false
previewView.addSubview(viewfinderShapeType)
viewfinderShapeType.topAnchor.constraint(equalTo: viewFinderShapeLabel.bottomAnchor, constant: 10).isActive = true
viewfinderShapeType.centerXAnchor.constraint(equalTo: previewView.centerXAnchor).isActive = true
stillImagePreviewView.translatesAutoresizingMaskIntoConstraints = false
stillImagePreviewView.contentMode = .scaleAspectFit
stillImagePreviewView.isUserInteractionEnabled = false
stillImagePreviewView.backgroundColor = .white
view.addSubview(stillImagePreviewView)
stillImagePreviewView.leadingAnchor.constraint(equalTo: previewView.leadingAnchor, constant: 0).isActive = true
stillImagePreviewView.trailingAnchor.constraint(equalTo: previewView.trailingAnchor, constant: 0).isActive = true
stillImagePreviewView.topAnchor.constraint(equalTo: viewfinderShapeType.bottomAnchor, constant: 20).isActive = true
stillImagePreviewView.bottomAnchor.constraint(equalTo: previewView.bottomAnchor, constant: 0).isActive = true
}
@objc fileprivate func change() {
if stillImagePreviewView.backgroundColor == .white {
stillImagePreviewView.backgroundColor = .systemOrange
} else {
stillImagePreviewView.backgroundColor = .white
}
}
}
Приятно, спасибо! Я изучаю это, чтобы понять, почему моя версия не работает... как и в вашей версии верхняя привязка для сегментированного элемента управления связана с нижней привязкой метки. Я попробовал ваши настройки в своем контроллере представления, и они работают.. все равно что-то в моих настройках нарушает его, и сегментированный элемент управления оказывается в верхнем левом углу.. Я наверняка неправильно устанавливаю некоторые параметры.
@Винченцо, где бы ты хотел это связать? Бок о бок? Объясните лучше, чтобы я мог решить ее для вас... Может быть, добавьте рисунок
это точно так же, как вы сделали. просто я устанавливал .translatesAutoresizingMaskIntoConstraints = false
для сегментированного элемента управления, а затем объявлял новый. см. ответ ДонМага. Спасибо за ответ и помощь
На самом деле в вашем коде viewfinderShapeType.translatesAutoresizingMaskIntoConstraints = false
это последняя строка настроек viewfinderShapeType
Вы создали сегментированный элемент управления как свойство вашего класса:
var viewfinderShapeType: UISegmentedControl = UISegmentedControl()
Причина, по которой ваш код помещает сегментированный элемент управления вверху слева, связана с этими двумя строками:
viewfinderShapeType.translatesAutoresizingMaskIntoConstraints = false
viewfinderShapeType = UISegmentedControl(items: ["RETTANGOLARE", "QUADRATA"])
Первая строка устанавливает .translatesAutoresizingMaskIntoConstraints = false
для элемента управления, который является свойством вашего класса.
Вторая строка создает НОВЫЙ UISegmentedControl
... для которого .translatesAutoresizingMaskIntoConstraints
не установлено в false
... и назначает этот новый элемент управления свойству класса.
Вы можете либо поменять порядок этих двух строк (создать новый экземпляр, а затем установить переводы...), либо
объявите свой контроль следующим образом:
var viewfinderShapeType: UISegmentedControl = {
let v = UISegmentedControl(items: ["RETTANGOLARE", "QUADRATA"])
return v
}()
и избавьтесь от этой строки:
//viewfinderShapeType = UISegmentedControl(items: ["RETTANGOLARE", "QUADRATA"])
вот и все! вот почему... можно ли с уверенностью предположить, что .translatesAutoresizingMaskIntoConstraints = false
следует установить последним?
@Vincenzo — по умолчанию при создании объекта пользовательского интерфейса для него установлено значение true. Итак, его просто нужно установить на экземпляре/объекте после его создания.
конечно, я не мог видеть, что создаю новый сегментированный элемент управления вместо того, чтобы просто назначать элементы пустому элементу, созданному в свойствах ViewController. Это было нормально для метки, установленной в первую очередь, но не для сегментированного элемента управления, поскольку я фактически создавал новый и назначал его свойству ViewController, и ходил по кругу. еще раз спасибо
Нет смысла устанавливать одновременно ведущие/конечные привязки и привязку centerx. Либо установите центр и ширину, либо установите ведущие/конечные привязки.