Ios UICollectionView装饰视图
是否有人为iOS 6 UICollectionView实现了装饰视图?这是不可能的Ios UICollectionView装饰视图,ios,ios6,uicollectionview,Ios,Ios6,Uicollectionview,是否有人为iOS 6 UICollectionView实现了装饰视图?这是不可能的 查找有关在web上实现装饰视图的任何教程。基本上,在我的应用程序中,我有多个部分,我只想在每个部分后面显示一个装饰视图。这应该是简单的实现,但我没有运气。这让我快发疯了。。。谢谢。我通过自定义布局获得了以下内容: 创建UICollectionReusableView的子类,例如向其添加UIImageView: @implementation AULYFloorPlanDecorationViewCell - (
查找有关在web上实现装饰视图的任何教程。基本上,在我的应用程序中,我有多个部分,我只想在每个部分后面显示一个装饰视图。这应该是简单的实现,但我没有运气。这让我快发疯了。。。谢谢。我通过自定义布局获得了以下内容: 创建UICollectionReusableView的子类,例如向其添加UIImageView:
@implementation AULYFloorPlanDecorationViewCell
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
UIImage *backgroundImage = [UIImage imageNamed:@"Layout.png"];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame];
imageView.image = backgroundImage;
[self addSubview:imageView];
}
return self;
}
@end
然后在viewDidLoad中的控制器中,用以下代码注册此子类(用自定义布局替换代码)
然后在自定义布局中实现以下方法(或类似方法):
-(UICollectionViewLayoutAttributes*)layoutAttributesForDecorationViewOfKind:(NSString*)decorationViewKind atIndexPath:(NSIndexPath*)indexPath
{
UICollectionViewLayoutAttributes*layoutAttributes=[UICollectionViewLayoutAttributes layoutAttributes layoutAttributes ForDecorrationViewOfKind:decorationViewKind withIndexPath:indexPath];
layoutAttributes.frame=CGRectMake(0.0,0.0,self.collectionViewContentSize.width,self.collectionViewContentSize.height);
layouttributes.zIndex=-1;
返回布局属性;
}
-(NSArray*)布局属性ForElementsInRect:(CGRect)rect
{
NSMutableArray*allAttributes=[[NSMutableArray alloc]initWithCapacity:4];
[allAttributes addObject:[self-layoutAttributesForDecorationViewOfKind:@“FloorPlan”atIndexPath:[NSIndexPath indexPathForItem:0第0节]];
对于(NSInteger i=0;i<[self.collectionView numberofitemsin部分:0];i++)
{
NSIndexPath*indexPath=[NSIndexPath indexPathForItem:i第1节:0];
UICollectionViewLayoutAttributes*layoutAttributes=[self-layoutAttributesForItemAtIndexPath:indexPath];
[allAttributes addObject:layoutAttributes];
}
返回所有属性;
}
似乎没有相关文档,但以下文档让我走上了正确的道路:
更新:可能最好将UICollectionReusableView子类化为装饰视图,而不是UICollectionViewCell
public class DecorationView : UICollectionReusableView
{
private static NSString classId = new NSString ("DecorationView");
public static NSString ClassId { get { return classId; } }
UIImageView blueMarble;
[Export("initWithFrame:")]
public DecorationView (RectangleF frame) : base(frame)
{
blueMarble = new UIImageView (UIImage.FromBundle ("bluemarble.png"));
AddSubview (blueMarble);
}
}
public class SimpleCollectionViewController : UICollectionViewController
{
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
//Register the cell class (code for AnimalCell snipped)
CollectionView.RegisterClassForCell (typeof(AnimalCell), AnimalCell.ClassId);
//Register the supplementary view class (code for SideSupplement snipped)
CollectionView.RegisterClassForSupplementaryView (typeof(SideSupplement), UICollectionElementKindSection.Header, SideSupplement.ClassId);
//Register the decoration view
CollectionView.CollectionViewLayout.RegisterClassForDecorationView (typeof(DecorationView), DecorationView.ClassId);
}
//...snip...
}
public class LineLayout : UICollectionViewFlowLayout
{
public override UICollectionViewLayoutAttributes[] LayoutAttributesForElementsInRect (RectangleF rect)
{
var array = base.LayoutAttributesForElementsInRect (rect);
/*
...snip content relating to cell layout...
*/
//Add decoration view
var attributesWithDecoration = new List<UICollectionViewLayoutAttributes> (array.Length + 1);
attributesWithDecoration.AddRange (array);
var decorationIndexPath = NSIndexPath.FromIndex (0);
var decorationAttributes = LayoutAttributesForDecorationView (DecorationView.ClassId, decorationIndexPath);
attributesWithDecoration.Add (decorationAttributes);
var extended = attributesWithDecoration.ToArray<UICollectionViewLayoutAttributes> ();
return extended;
}
public override UICollectionViewLayoutAttributes LayoutAttributesForDecorationView (NSString kind, NSIndexPath indexPath)
{
var layoutAttributes = UICollectionViewLayoutAttributes.CreateForDecorationView (kind, indexPath);
layoutAttributes.Frame = new RectangleF (0, 0, CollectionView.ContentSize.Width, CollectionView.ContentSize.Height);
layoutAttributes.ZIndex = -1;
return layoutAttributes;
}
//...snip...
}
公共类装饰视图:UICollectionReusableView
{
私有静态NSString classId=新NSString(“装饰视图”);
公共静态NSString ClassId{get{return ClassId;}}
UIImageView蓝色大理石;
[导出(“initWithFrame:”)]
公共装饰视图(矩形框架):基础(框架)
{
Blue大理石=新的UIImageView(UIImage.FromBundle(“blueMarble.png”);
添加子视图(蓝色大理石);
}
}
公共类SimpleCollectionViewController:UICollectionViewController
{
公共覆盖无效ViewDidLoad()
{
base.ViewDidLoad();
//注册单元类(AnimalCell snipped的代码)
CollectionView.RegisterClassForCell(typeof(AnimalCell),AnimalCell.ClassId);
//注册补充视图类(侧边补充剪下的代码)
CollectionView.RegisterClassForSupplementaryView(typeof(SideReplacement),UICollectionElementKindSection.Header,SideReplacement.ClassId);
//注册装饰视图
CollectionView.CollectionViewLayout.RegisterClassForDecorationView(typeof(DecorationView),DecorationView.ClassId);
}
//…剪断。。。
}
公共类LineLayout:UICollectionViewFlowLayout
{
公共覆盖UICollectionViewLayoutAttributes[]LayoutAttributesForElementsInRect(RectangleF rect)
{
var数组=base.layouttributesforementsinrect(rect);
/*
…剪切与单元格布局相关的内容。。。
*/
//添加装饰视图
var attributesWithDecoration=新列表(array.Length+1);
attributesWithDecoration.AddRange(数组);
var decorationIndexPath=nsindepath.FromIndex(0);
var decorationAttributes=layouttributesfordecorationview(DecorationView.ClassId,decorationIndexPath);
添加(装饰属性);
var extended=attributesWithDecoration.ToArray();
回报延长;
}
公共重写UICollectionViewLayoutAttributes LayoutAttributesForDecorationView(NSString类,NSIndexPath indexPath)
{
var layoutAttributes=UICollectionViewLayoutAttributes.CreateForDecorationView(种类,indexPath);
LayoutAttribute.Frame=新矩形F(0,0,CollectionView.ContentSize.Width,CollectionView.ContentSize.Height);
layouttributes.ZIndex=-1;
返回布局属性;
}
//…剪断。。。
}
最终结果类似于:
这是Swift中的集合视图布局装饰视图教程(这是Swift 3,Xcode 8 seed 6)
装饰视图不是UICollectionView功能;它们本质上属于UICollectionViewLayout。没有UICollectionView方法(或委托或数据源方法)提到装饰视图。UICollectionView对它们一无所知;它只是做它被告知的事情 要提供任何装饰视图,需要UICollectionViewLayout子类;这个子类可以自由定义自己的属性和委托协议方法,这些方法可以自定义装饰视图的配置方式,但这完全取决于您 为了说明这一点,我将为UICollectionViewFlowLayout创建子类,以便在集合视图的内容矩形顶部添加一个标题标签。这可能是对装饰视图的愚蠢使用,但它完美地说明了基本原则。为了简单起见,我将从硬编码开始,让客户机无法自定义此视图的任何方面 在布局子类中实现装饰视图有四个步骤:
class MyTitleView : UICollectionReusableView {
weak var lab : UILabel!
override init(frame: CGRect) {
super.init(frame:frame)
let lab = UILabel(frame:self.bounds)
self.addSubview(lab)
lab.autoresizingMask = [.flexibleWidth, .flexibleHeight]
lab.font = UIFont(name: "GillSans-Bold", size: 40)
lab.text = "Testing"
self.lab = lab
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Register(\ufo:fo),将UICollectionReusableView子类注册到布局中(而不是集合视图)
public class DecorationView : UICollectionReusableView
{
private static NSString classId = new NSString ("DecorationView");
public static NSString ClassId { get { return classId; } }
UIImageView blueMarble;
[Export("initWithFrame:")]
public DecorationView (RectangleF frame) : base(frame)
{
blueMarble = new UIImageView (UIImage.FromBundle ("bluemarble.png"));
AddSubview (blueMarble);
}
}
public class SimpleCollectionViewController : UICollectionViewController
{
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
//Register the cell class (code for AnimalCell snipped)
CollectionView.RegisterClassForCell (typeof(AnimalCell), AnimalCell.ClassId);
//Register the supplementary view class (code for SideSupplement snipped)
CollectionView.RegisterClassForSupplementaryView (typeof(SideSupplement), UICollectionElementKindSection.Header, SideSupplement.ClassId);
//Register the decoration view
CollectionView.CollectionViewLayout.RegisterClassForDecorationView (typeof(DecorationView), DecorationView.ClassId);
}
//...snip...
}
public class LineLayout : UICollectionViewFlowLayout
{
public override UICollectionViewLayoutAttributes[] LayoutAttributesForElementsInRect (RectangleF rect)
{
var array = base.LayoutAttributesForElementsInRect (rect);
/*
...snip content relating to cell layout...
*/
//Add decoration view
var attributesWithDecoration = new List<UICollectionViewLayoutAttributes> (array.Length + 1);
attributesWithDecoration.AddRange (array);
var decorationIndexPath = NSIndexPath.FromIndex (0);
var decorationAttributes = LayoutAttributesForDecorationView (DecorationView.ClassId, decorationIndexPath);
attributesWithDecoration.Add (decorationAttributes);
var extended = attributesWithDecoration.ToArray<UICollectionViewLayoutAttributes> ();
return extended;
}
public override UICollectionViewLayoutAttributes LayoutAttributesForDecorationView (NSString kind, NSIndexPath indexPath)
{
var layoutAttributes = UICollectionViewLayoutAttributes.CreateForDecorationView (kind, indexPath);
layoutAttributes.Frame = new RectangleF (0, 0, CollectionView.ContentSize.Width, CollectionView.ContentSize.Height);
layoutAttributes.ZIndex = -1;
return layoutAttributes;
}
//...snip...
}
class MyTitleView : UICollectionReusableView {
weak var lab : UILabel!
override init(frame: CGRect) {
super.init(frame:frame)
let lab = UILabel(frame:self.bounds)
self.addSubview(lab)
lab.autoresizingMask = [.flexibleWidth, .flexibleHeight]
lab.font = UIFont(name: "GillSans-Bold", size: 40)
lab.text = "Testing"
self.lab = lab
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
private let titleKind = "title"
private let titleHeight : CGFloat = 50
private var titleRect : CGRect {
return CGRect(10,0,200,self.titleHeight)
}
override init() {
super.init()
self.register(MyTitleView.self, forDecorationViewOfKind:self.titleKind)
}
override func layoutAttributesForDecorationView(
ofKind elementKind: String, at indexPath: IndexPath)
-> UICollectionViewLayoutAttributes? {
if elementKind == self.titleKind {
let atts = UICollectionViewLayoutAttributes(
forDecorationViewOfKind:self.titleKind, with:indexPath)
atts.frame = self.titleRect
return atts
}
return nil
}
override func layoutAttributesForElements(in rect: CGRect)
-> [UICollectionViewLayoutAttributes]? {
var arr = super.layoutAttributesForElements(in: rect)!
if let decatts = self.layoutAttributesForDecorationView(
ofKind:self.titleKind, at: IndexPath(item: 0, section: 0)) {
if rect.intersects(decatts.frame) {
arr.append(decatts)
}
}
return arr
}
class MyFlowLayout : UICollectionViewFlowLayout {
var title = ""
// ...
}
func setUpFlowLayout(_ flow:UICollectionViewFlowLayout) {
flow.headerReferenceSize = CGSize(50,50)
flow.sectionInset = UIEdgeInsetsMake(0, 10, 10, 10)
(flow as? MyFlowLayout)?.title = "States" // *
}
class MyTitleViewLayoutAttributes : UICollectionViewLayoutAttributes {
var title = ""
}
override func layoutAttributesForDecorationView(
ofKind elementKind: String, at indexPath: IndexPath) ->
UICollectionViewLayoutAttributes? {
if elementKind == self.titleKind {
let atts = MyTitleViewLayoutAttributes( // *
forDecorationViewOfKind:self.titleKind, with:indexPath)
atts.title = self.title // *
atts.frame = self.titleRect
return atts
}
return nil
}
class MyTitleView : UICollectionReusableView {
weak var lab : UILabel!
// ... the rest as before ...
override func apply(_ atts: UICollectionViewLayoutAttributes) {
if let atts = atts as? MyTitleViewLayoutAttributes {
self.lab.text = atts.title
}
}
}