gpt4 book ai didi

ios - UIScrollView 及其子项 : why are they placed on top of each other? (AutoLayout)

转载 作者:行者123 更新时间:2023-11-28 05:33:41 31 4
gpt4 key购买 nike

我正在开发一款应用,用户可以在其中向订单中添加产品。每个产品都有自己的 UIView,所有这些产品都放在一个 UI 中(并放在一个数组中以供将来引用,如总价等)。我对添加产品并没有做太多花哨的事情:

/* Create the new product */        
var tmp = Product(data: product)
/* Add it to the scrollView */
scrollView.addSubview(tmp)

我正在为 UIScrollView 本身使用 AutoLayout,但没有设置约束(我也已清除它以进行检查)。

澄清一下:Product 是 UIView 的子类,只是为了标准化每个产品的外观。

但是,当我添加超过 1 个产品时,新产品会放置在第一个产品之上,而不是第一个产品之下。我有一种感觉,我错过了使用具有自动布局的 UIScrollView 的关键部分。谁能指出我正确的方向?

编辑:最后我通过创建一个方法来解决它(重新)计算位置,因为我在 UICollectionView 中得到了相同的行为。我在 Android 中开发同一个应用程序,您可以让子元素充当 block (在 CSS 意义上)元素。我固执地在 iOS 中寻找相同的解决方案 :)

最佳答案

当您调用 [scrollView addSubview:productView];

时,UIScrollView 不会自动将您的 subview 定位在正确的位置

在将 subview 添加到 UIScrollView 之前,您需要使用 initWithFrame 告诉 subview 正确的位置,在这种情况下,您似乎正在使用自动布局。

如果您对替代方案持开放态度,我认为 UICollectionView 可以实现您想要的。 Collection View 中的每个“单元格”都是您的产品 View 。 Collection View 具有 ScrollView 的所有功能。

如果您在产品 View 中使用框架,那么您可以这样做:

var view1:UIView = UIView(frame: CGRectMake(0, 0, 320, 480)];

// -----------------------------------------------------------------------
// Notice here, view2 has a Y position that takes the height of view1
//
// So we're telling iOS to put view2 right below view1 before we
// add it as a subview of our scrollView
// -----------------------------------------------------------------------
var view2:UIView = UIView(frame: CGRectMake(0, view1.frame.origin.y, 320, 480));

self.scrollView.addSubview(view1);
self.scrollView.addSubview(view2);

UICollectionView 自动布局演示:

为了完整起见,我将包含一个使用 Swift 的基本 UICollectionView Autolayout 演示。

View Controller

import UIKit

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

var arrItems:NSMutableArray = NSMutableArray();
var collectionView:UICollectionView?;

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.

self.arrItems.addObject("Apple");
self.arrItems.addObject("Banana");
self.arrItems.addObject("Orange");
self.arrItems.addObject("Mango");
self.arrItems.addObject("Watermelon");

initViews();
initConstraints();
}

override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}

func initViews()
{
// ------------------------------------------------------
// Init the collection View
// ------------------------------------------------------

var flowLayout:UICollectionViewFlowLayout = UICollectionViewFlowLayout();
flowLayout.itemSize = CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height / 2.0);

self.collectionView = UICollectionView(frame: CGRectZero, collectionViewLayout: flowLayout);
self.collectionView?.registerClass(ProductCell.self, forCellWithReuseIdentifier: "cellID");
self.collectionView?.delegate = self;
self.collectionView?.dataSource = self;
self.collectionView?.backgroundColor = UIColor.whiteColor();
self.collectionView?.pagingEnabled = true;

self.view.addSubview(self.collectionView!);
}

func initConstraints()
{
self.collectionView?.setTranslatesAutoresizingMaskIntoConstraints(false);

var views:NSMutableDictionary = NSMutableDictionary();

views.setValue(self.collectionView!, forKey: "collectionView");

self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[collectionView]|", options: nil, metrics: nil, views: views));
self.view.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[collectionView]|", options: nil, metrics: nil, views: views));
}

func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {


return self.arrItems.count;
}

func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

// ---------------------------------------------------
// Note, Swift is able to detect all developer's own
// class files, so no need to import ProductCell
// ---------------------------------------------------

// create a ProductCell
var cell:ProductCell = collectionView.dequeueReusableCellWithReuseIdentifier("cellID", forIndexPath: indexPath) as ProductCell;

// setup product info
cell.productName.text = self.arrItems[indexPath.row] as NSString;
cell.productDescription.text = "This is some text about the product. It can be a very long block of text or maybe a really short one. Up to you to design it anyway you like.";

return cell;
}

}

产品单元类

import UIKit

class ProductCell: UICollectionViewCell {
var container:UIView = UIView();
var productName:UILabel = UILabel();
var productDescription:UILabel = UILabel();

override init(frame: CGRect) {
super.init(frame: frame);

initViews();
initConstraints();
}

required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder);
}

func initViews()
{
self.container.backgroundColor = UIColor.lightGrayColor();
self.container.layer.cornerRadius = 5.0;

self.productName.font = UIFont.systemFontOfSize(14);
self.productName.textColor = UIColor.whiteColor();
self.productName.textAlignment = NSTextAlignment.Center;
self.productName.numberOfLines = 0;
self.productName.setContentHuggingPriority(1000, forAxis: UILayoutConstraintAxis.Vertical);
self.productName.backgroundColor = UIColor(red: 0.2, green: 0.2, blue: 0.8, alpha: 1.0);
self.productName.layer.cornerRadius = 5.0;
self.productName.clipsToBounds = true;

self.productDescription.font = UIFont.systemFontOfSize(14);
self.productDescription.numberOfLines = 0;

self.container.addSubview(self.productName);
self.container.addSubview(self.productDescription);

self.contentView.addSubview(self.container);
}

func initConstraints()
{
self.container.setTranslatesAutoresizingMaskIntoConstraints(false);
self.productName.setTranslatesAutoresizingMaskIntoConstraints(false);
self.productDescription.setTranslatesAutoresizingMaskIntoConstraints(false);

var views:NSMutableDictionary = NSMutableDictionary();
views.setValue(self.container, forKey: "container");
views.setValue(self.productName, forKey: "productName");
views.setValue(self.productDescription, forKey: "productDescription");

// container constraints
self.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-20-[container]-20-|", options: nil, metrics: nil, views: views));
self.contentView.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-20-[container]-20-|", options: nil, metrics: nil, views: views));

// subview constraints

self.container.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-10-[productName]-10-|", options: nil, metrics: nil, views: views));

self.container.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|-10-[productDescription]-10-|", options: nil, metrics: nil, views: views));

self.container.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|-10-[productName(50)]-10-[productDescription]-10-|", options: nil, metrics: nil, views: views));
}
}

你应该得到这样的结果:

screenshot of UICollectionView Swift demo

关于ios - UIScrollView 及其子项 : why are they placed on top of each other? (AutoLayout),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26233999/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com