Swift imageview 帧等于图像原始大小
Swift imageview frame is equal to image original size
使用图像创建 UIImageView 时,视图的框架设置为图像的原始大小。我想知道应用所有锚点约束后它的实际大小
我试过不同的图像,它们都做同样的事情。
有问题的 class 是:SuggestionCloud;
我会分三部分来解释这个问题:
第一个:设置所有 UI 元素并调用“错误”自定义 UIImage class (SuggestionCloud) 的 superclass。
第二:suggesionCloud Class
UIScaleControllerVew
Class UIScaleControllerView: UIViewController: {
let suggestionCloud : SuggenstionCloud = {
let cloud = SuggenstionCloud(image: UIImage(named: "suggestionCloud.png"))
cloud.translatesAutoresizingMaskIntoConstraints = false;
return cloud;
}();
override func viewDidLoad() {
super.viewDidLoad()
print("UIScaleController_DidLoad")
view.backgroundColor = UIColor(hexString: "8ED7F5")
view.addSubview(weigtImageView)
view.addSubview(textView)
view.addSubview(bottomMenu);
view.addSubview(suggestionCloud)
setUpLayout()
suggestionCloud.setLabels(weightedTags: stuff, selectedTags: selected)
}
extension UIScaleControllerVew {
func setUpLayout() {
// SuggestionCloud
suggestionCloud.setConstraints(
topAnchor: textView.bottomAnchor, topConstant: 0,
bottomAnchor: bottomMenu.topAnchor, bottomConstant: 0,
trailingAnchor: view.trailingAnchor, trailingConstant: 10,
leadingAnchor: view.leadingAnchor, leadingConstant: 10
//all UI elements are setup underneath..took those out for th
suggestionCloud Class:
进口UI套件
class SuggenstionCloud:UIImageView {
override init(image: UIImage?) {
super.init(image: image)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public func setConstraints(
topAnchor : NSLayoutAnchor<NSLayoutYAxisAnchor>, topConstant: CGFloat,
bottomAnchor: NSLayoutAnchor<NSLayoutYAxisAnchor>, bottomConstant: CGFloat,
trailingAnchor: NSLayoutAnchor<NSLayoutXAxisAnchor>, trailingConstant: CGFloat,
leadingAnchor: NSLayoutAnchor<NSLayoutXAxisAnchor>, leadingConstant: CGFloat)
{
self.contentMode = .scaleToFill
self.topAnchor.constraint(equalTo: topAnchor, constant: topConstant).isActive = true;
self.bottomAnchor.constraint(equalTo: bottomAnchor, constant: bottomConstant).isActive = true;
self.trailingAnchor.constraint(equalTo: trailingAnchor, constant: trailingConstant).isActive = true;
self.leadingAnchor.constraint(equalTo: leadingAnchor, constant: leadingConstant).isActive = true;
}
public func setLabels(weightedTags: [String: Int], selectedTags: [String]) {
let buttons : [UIButton] = createButtons(weightedTags: weightedTags);
createLayout(buttons: buttons)
}
private func createButton(buttonText: String) -> UIButton {
let button = UIButton()
button.setTitle(buttonText, for: .normal)
button.titleLabel?.font = UIFont(name: "Avenir-Light", size: 20.0)
button.translatesAutoresizingMaskIntoConstraints = false;
button.backgroundColor = .blue
self.addSubview(button)
return button;
}
private func createButtons(weightedTags: [String: Int]) -> [UIButton] {
var buttons : [UIButton] = [];
for tag in weightedTags {
buttons.append(createButton(buttonText: tag.key))
}
return buttons;
}
private func createLayout(buttons : [UIButton]) {
if buttons.count == 0 { return }
let leftEdgePadding : CGFloat = 30;
let rightEdgePadding : CGFloat = 30;
let topPadding : CGFloat = 30;
let padding : CGFloat = 10;
let availableHeight : CGFloat = self.frame.height + (-2 * topPadding)
let availableWidth : CGFloat = self.frame.width + (-2 * padding)
var i = 0;
var totalHeight : CGFloat = 0;
var rowLength : CGFloat = 0;
var rowCount : Int = 0;
var lastButton : UIButton!
for button in buttons {
if totalHeight > availableHeight {print("Cloud out of space"); return}
if rowLength == 0 && rowCount == 0
{
setFirstConstraints(button: button, padding: topPadding)
totalHeight = button.intrinsicContentSize.height + topPadding;
rowLength += button.intrinsicContentSize.width + padding
lastButton = button;
}
else if rowLength + button.intrinsicContentSize.width < availableWidth
{
setConstraints(button, padding, topPadding, lastButton, rowCount)
rowLength += button.intrinsicContentSize.width + padding;
lastButton = button;
}
else
{
totalHeight += button.intrinsicContentSize.height + padding
setNewRowConstraint(button: button, padding: padding, totalHeight: totalHeight)
rowLength = 0;
rowCount += 1
lastButton = button
}
i += 1;
}
}
private func setNewRowConstraint(
button: UIButton,
padding: CGFloat,
totalHeight: CGFloat)
{
let totalPadding = button.intrinsicContentSize.height + padding + totalHeight
button.topAnchor.constraint(equalTo: self.topAnchor, constant: totalHeight).isActive = true
button.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: padding).isActive = true
}
private func setConstraints (
_ button : UIButton,
_ leftPadding: CGFloat,
_ topPadding: CGFloat ,
_ lastButton: UIButton,
_ rows: Int)
{
button.leadingAnchor.constraint(equalTo: lastButton.trailingAnchor, constant: leftPadding).isActive = true
button.topAnchor.constraint(equalTo: self.topAnchor, constant: topPadding).isActive = true
}
private func setFirstConstraints(button: UIButton, padding: CGFloat)
{
button.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: padding).isActive = true
button.topAnchor.constraint(equalTo: self.topAnchor, constant: padding ).isActive = true
}
}
第三:终于是问题了:
我正在动态创建按钮以适应视图。
我必须以编程方式设置每个按钮的锚点以适合它们的 supeclass's 。动态维度。
但是:在我的算法中 self.frame.size 是:800,800:init() 时的原始图像大小。
let availableHeight : CGFloat = self.frame.height // = 800
let availableWidth : CGFloat = self.frame.width // 800 no bueno
奇怪的是 UIView 的实际大小在模拟器中是正确的。所以约束有效,但图像视图不知道它的实际尺寸
谁能帮我解决这个问题?我做错了什么?
调用设置标签的时间过早。调用 viewDidLoad 时未设置框架。您需要等到 viewDidLayoutSubviews/layoutSubviews 之后。使用标志并在 didLayoutSubviews 中进行设置应该可以让您正确读取框架。
var didSetUpSuggestionCloud = false
override func viewDidLoad() {
super.viewDidLoad()
print("UIScaleController_DidLoad")
view.backgroundColor = UIColor(hexString: "8ED7F5")
view.addSubview(weigtImageView)
view.addSubview(textView)
view.addSubview(bottomMenu);
view.addSubview(suggestionCloud)
setUpLayout()
//make sure suggestionClouds setConstraints is called here
}
override func viewDidLayoutSubviews() {
guard !self.didSetUpSuggestionCloud else {
return
}
suggestionCloud.setLabels(weightedTags: stuff, selectedTags: selected)
self.didSetUpSuggestionCloud = true
}
一个标志是必要的,因为 viewDidLayoutSubviews 在整个视图控制器生命周期中可以被多次调用。
使用图像创建 UIImageView 时,视图的框架设置为图像的原始大小。我想知道应用所有锚点约束后它的实际大小
我试过不同的图像,它们都做同样的事情。
有问题的 class 是:SuggestionCloud; 我会分三部分来解释这个问题:
第一个:设置所有 UI 元素并调用“错误”自定义 UIImage class (SuggestionCloud) 的 superclass。
第二:suggesionCloud Class
UIScaleControllerVew
Class UIScaleControllerView: UIViewController: {
let suggestionCloud : SuggenstionCloud = {
let cloud = SuggenstionCloud(image: UIImage(named: "suggestionCloud.png"))
cloud.translatesAutoresizingMaskIntoConstraints = false;
return cloud;
}();
override func viewDidLoad() {
super.viewDidLoad()
print("UIScaleController_DidLoad")
view.backgroundColor = UIColor(hexString: "8ED7F5")
view.addSubview(weigtImageView)
view.addSubview(textView)
view.addSubview(bottomMenu);
view.addSubview(suggestionCloud)
setUpLayout()
suggestionCloud.setLabels(weightedTags: stuff, selectedTags: selected)
}
extension UIScaleControllerVew {
func setUpLayout() {
// SuggestionCloud
suggestionCloud.setConstraints(
topAnchor: textView.bottomAnchor, topConstant: 0,
bottomAnchor: bottomMenu.topAnchor, bottomConstant: 0,
trailingAnchor: view.trailingAnchor, trailingConstant: 10,
leadingAnchor: view.leadingAnchor, leadingConstant: 10
//all UI elements are setup underneath..took those out for th
suggestionCloud Class:
进口UI套件
class SuggenstionCloud:UIImageView {
override init(image: UIImage?) {
super.init(image: image)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
public func setConstraints(
topAnchor : NSLayoutAnchor<NSLayoutYAxisAnchor>, topConstant: CGFloat,
bottomAnchor: NSLayoutAnchor<NSLayoutYAxisAnchor>, bottomConstant: CGFloat,
trailingAnchor: NSLayoutAnchor<NSLayoutXAxisAnchor>, trailingConstant: CGFloat,
leadingAnchor: NSLayoutAnchor<NSLayoutXAxisAnchor>, leadingConstant: CGFloat)
{
self.contentMode = .scaleToFill
self.topAnchor.constraint(equalTo: topAnchor, constant: topConstant).isActive = true;
self.bottomAnchor.constraint(equalTo: bottomAnchor, constant: bottomConstant).isActive = true;
self.trailingAnchor.constraint(equalTo: trailingAnchor, constant: trailingConstant).isActive = true;
self.leadingAnchor.constraint(equalTo: leadingAnchor, constant: leadingConstant).isActive = true;
}
public func setLabels(weightedTags: [String: Int], selectedTags: [String]) {
let buttons : [UIButton] = createButtons(weightedTags: weightedTags);
createLayout(buttons: buttons)
}
private func createButton(buttonText: String) -> UIButton {
let button = UIButton()
button.setTitle(buttonText, for: .normal)
button.titleLabel?.font = UIFont(name: "Avenir-Light", size: 20.0)
button.translatesAutoresizingMaskIntoConstraints = false;
button.backgroundColor = .blue
self.addSubview(button)
return button;
}
private func createButtons(weightedTags: [String: Int]) -> [UIButton] {
var buttons : [UIButton] = [];
for tag in weightedTags {
buttons.append(createButton(buttonText: tag.key))
}
return buttons;
}
private func createLayout(buttons : [UIButton]) {
if buttons.count == 0 { return }
let leftEdgePadding : CGFloat = 30;
let rightEdgePadding : CGFloat = 30;
let topPadding : CGFloat = 30;
let padding : CGFloat = 10;
let availableHeight : CGFloat = self.frame.height + (-2 * topPadding)
let availableWidth : CGFloat = self.frame.width + (-2 * padding)
var i = 0;
var totalHeight : CGFloat = 0;
var rowLength : CGFloat = 0;
var rowCount : Int = 0;
var lastButton : UIButton!
for button in buttons {
if totalHeight > availableHeight {print("Cloud out of space"); return}
if rowLength == 0 && rowCount == 0
{
setFirstConstraints(button: button, padding: topPadding)
totalHeight = button.intrinsicContentSize.height + topPadding;
rowLength += button.intrinsicContentSize.width + padding
lastButton = button;
}
else if rowLength + button.intrinsicContentSize.width < availableWidth
{
setConstraints(button, padding, topPadding, lastButton, rowCount)
rowLength += button.intrinsicContentSize.width + padding;
lastButton = button;
}
else
{
totalHeight += button.intrinsicContentSize.height + padding
setNewRowConstraint(button: button, padding: padding, totalHeight: totalHeight)
rowLength = 0;
rowCount += 1
lastButton = button
}
i += 1;
}
}
private func setNewRowConstraint(
button: UIButton,
padding: CGFloat,
totalHeight: CGFloat)
{
let totalPadding = button.intrinsicContentSize.height + padding + totalHeight
button.topAnchor.constraint(equalTo: self.topAnchor, constant: totalHeight).isActive = true
button.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: padding).isActive = true
}
private func setConstraints (
_ button : UIButton,
_ leftPadding: CGFloat,
_ topPadding: CGFloat ,
_ lastButton: UIButton,
_ rows: Int)
{
button.leadingAnchor.constraint(equalTo: lastButton.trailingAnchor, constant: leftPadding).isActive = true
button.topAnchor.constraint(equalTo: self.topAnchor, constant: topPadding).isActive = true
}
private func setFirstConstraints(button: UIButton, padding: CGFloat)
{
button.leadingAnchor.constraint(equalTo: self.leadingAnchor, constant: padding).isActive = true
button.topAnchor.constraint(equalTo: self.topAnchor, constant: padding ).isActive = true
}
}
第三:终于是问题了: 我正在动态创建按钮以适应视图。 我必须以编程方式设置每个按钮的锚点以适合它们的 supeclass's 。动态维度。
但是:在我的算法中 self.frame.size 是:800,800:init() 时的原始图像大小。
let availableHeight : CGFloat = self.frame.height // = 800
let availableWidth : CGFloat = self.frame.width // 800 no bueno
奇怪的是 UIView 的实际大小在模拟器中是正确的。所以约束有效,但图像视图不知道它的实际尺寸
谁能帮我解决这个问题?我做错了什么?
调用设置标签的时间过早。调用 viewDidLoad 时未设置框架。您需要等到 viewDidLayoutSubviews/layoutSubviews 之后。使用标志并在 didLayoutSubviews 中进行设置应该可以让您正确读取框架。
var didSetUpSuggestionCloud = false
override func viewDidLoad() {
super.viewDidLoad()
print("UIScaleController_DidLoad")
view.backgroundColor = UIColor(hexString: "8ED7F5")
view.addSubview(weigtImageView)
view.addSubview(textView)
view.addSubview(bottomMenu);
view.addSubview(suggestionCloud)
setUpLayout()
//make sure suggestionClouds setConstraints is called here
}
override func viewDidLayoutSubviews() {
guard !self.didSetUpSuggestionCloud else {
return
}
suggestionCloud.setLabels(weightedTags: stuff, selectedTags: selected)
self.didSetUpSuggestionCloud = true
}
一个标志是必要的,因为 viewDidLayoutSubviews 在整个视图控制器生命周期中可以被多次调用。