Waterfall flow is one of the ways in which electrical business applications display goods, such as illustrations
Waterfall flows are implemented in the following ways, usually
- Implemented via UITableView (not commonly used)
- Implemented through Uiscrollview (larger workload)
- Implemented through Uicollectionview (usually in the manner used)
First, Uicollectionview Foundation
1, Uicollectionview and UITableView have a lot of similar places, such as
- Provide data through the data source
- Performs related events through the agent
- You can customize the cell and involve cell reuse.
- are inherited from Uiscrollview, with scrolling effects
2, the characteristics of Uicollectionview
- You need to have a uicollectionviewlayout class (usually the Uicollectionviewflowlayout class) or its subclass object to determine the layout of the cell
- You can implement uicollectionviewlayout subclasses to customize the scrolling direction of Uicollectionview and the layout of the cell
3, Uicollectionviewlayout of the subclass Uicollectionviewflowlayout
- Uicollectionviewflowlayout is the flow layout
- One of the most commonly used layout methods for flow layout Uicollectionview
Two, custom layout
1, custom layout needs to implement Uicollectionviewlayout subclass
2, custom layout common methods
Initialize Layout
-(void) preparelayout
{
//typically completes a layout initialization operation in this method
}
Whether to update the layout when the dimension changes
-(BOOL) Shouldinvalidatelayoutforboundschange: (cgrect) newbounds
{
//default return Yes
}
Elements of Layout Uicollectionview
-(Nullable nsarray<__kindof uicollectionviewlayoutattributes *> *) Layoutattributesforelementsinrect: (CGRect) Rect
{
//This method needs to return an array of all the element layout properties in the Rect area
}
-(Nullable uicollectionviewlayoutattributes *) Layoutattributesforitematindexpath: (Nsindexpath *) Indexpath
{
//This method returns the layout properties of the element at Indexpath position
}
Modify Uicollectionview Stop scrolling offset
-(Cgpoint) Targetcontentoffsetforproposedcontentoffset: (cgpoint) Proposedcontentoffset withScrollingVelocity: ( Cgpoint) Velocity
{
//return value is, Uicollectionview final stop point
}
Third, the example
1, realize the effect
2, the realization of ideas
- Implemented by Uicollectionview
- Custom layout, i.e. horizontal flow layout and circular general layout
- By Uicollectionview's proxy method, when you click on the cell, delete it
- Change the layout when you point to the view of the controller by listening to the UIView touch events
3. Implementation steps
self-defined transverse flow layout
Initialize Layout
-(void) preparelayout
{
[super preparelayout];
Set scrolling direction
self.scrolldirection = uicollectionviewscrolldirectionhorizontal;
Set the inner margin
cgfloat inset = (self.collectionview.frame.size.width-self.itemsize.width) * 0.5;
Self.sectioninset = Uiedgeinsetsmake (0, inset, 0, inset);
}
Specifies that when a dimension changes, the layout is updated
-(BOOL) Shouldinvalidatelayoutforboundschange: (cgrect) newbounds
{return
YES;
}
Set layout properties for all elements
-(Nullable nsarray<uicollectionviewlayoutattributes *> *) Layoutattributesforelementsinrect: (CGRect) rect
{
//Get the layout properties of all elements in the Rect area
nsarray *array = [Super Layoutattributesforelementsinrect:rect];
Gets the midpoint of the Uicollectionview, taking the upper-left corner of the Contentview as the origin
cgfloat CenterX = self.collectionview.contentoffset.x + Self.collectionView.frame.size.width * 0.5;
Resets the layout properties of all elements in the Rect area, that is, based on their intensity from the midpoint of the Uicollectionview, to change their size for
(Uicollectionviewlayoutattributes *attribute in Array)
{
//get distance from midpoint
cgfloat delta = ABS (Attribute.center.x-centerx);
Compute the scaling ratio
cgfloat scale = 1-delta/self.collectionview.bounds.size.width;
Set layout properties
Attribute.transform = Cgaffinetransformmakescale (scale, scale);
}
Returns the layout properties for all elements return
[array copy];
}
Sets the offset of the Uicollectionview stop scroll to the center point
-(Cgpoint) Targetcontentoffsetforproposedcontentoffset: (cgpoint) Proposedcontentoffset withScrollingVelocity: ( Cgpoint) Velocity
{
//Compute the final displayed rectangular frame
cgrect rect;
rect.origin.x = proposedcontentoffset.x;
RECT.ORIGIN.Y = 0;
Rect.size = self.collectionView.frame.size;
Gets the layout properties of the element that is ultimately displayed in the rectangle box
nsarray *array = [Super Layoutattributesforelementsinrect:rect];
Gets the midpoint of the Uicollectionview, taking the upper-left corner of the Contentview as the origin
cgfloat CenterX = proposedcontentoffset.x + Self.collectionView.frame.size.width * 0.5;
Gets the shortest distance of all elements to the midpoint
cgfloat mindelta = maxfloat;
For (uicollectionviewlayoutattributes *attribute in array)
{
CGFloat delta = attribute.center.x-centerx;< C16/>if (ABS (Mindelta) > abs (Delta))
{
mindelta = Delta;
}
}
Change the uicollectionview of the offset
proposedcontentoffset.x + = Mindelta;
return proposedcontentoffset;
}
Custom Round general Layout
Define member properties, save all layout properties
@property (nonatomic, strong) Nsmutablearray *attrsarray;
Lazy load, initialize Attrsarray
-(Nsmutablearray *) Attrsarray
{
if (_attrsarray = = nil)
{
_attrsarray = [Nsmutablearray array];
} return
_attrsarray;
}
Initialize layout
-(void) preparelayout
{
[super preparelayout];
Remove all old layout Properties
[Self.attrsarray removeallobjects];
Gets the number of elements
nsinteger count = [Self.collectionview numberofitemsinsection:0];
Layout all elements for
(Nsinteger i = 0; i<count; i++)
{
Nsindexpath *indexpath = [Nsindexpath indexpathforitem : I insection:0];
Sets and gets the layout properties of the Indexpath location element
uicollectionviewlayoutattributes *attrs = [Self Layoutattributesforitematindexpath: Indexpath];
Adds the layout property of the Indexpath location element to all layout property Arrays
[Self.attrsarray addobject:attrs];
}
Elements of the layout Indexpath position
-(Nullable Uicollectionviewlayoutattributes *) Layoutattributesforitematindexpath: (nonnull nsindexpath *) IndexPath
{
//Get the number of elements
nsinteger count = [Self.collectionview numberofitemsinsection:0];
/** Set the center layout//
/Set the radius of the circle
cgfloat radius =;
The position of the center
cgfloat OX = self.collectionView.frame.size.width * 0.5;
CGFloat OY = self.collectionView.frame.size.height * 0.5;
Gets the layout properties of the element for the Indexpath position
uicollectionviewlayoutattributes *attrs = [uicollectionviewlayoutattributes Layoutattributesforcellwithindexpath:indexpath];
Set dimension
attrs.size = Cgsizemake (m);
Set position
if (count = = 1)
{
attrs.center = Cgpointmake (OX, OY);
}
else
{
CGFloat angle = (2 * m_pi/count) * INDEXPATH.ITEM;
CGFloat CenterX = oX + radius * sin (angle);
CGFloat CenterY = oY + radius * cos (angle);
Attrs.center = Cgpointmake (CenterX, centery);
}
Returns the Layout property of the Indexpath position element return
attrs.
}
Layout all elements within a specified area
-(Nullable nsarray<uicollectionviewlayoutattributes *> *) Layoutattributesforelementsinrect: (CGRect) rect
{
//returns the layout properties of all elements return
Self.attrsarray;
}
Custom CE ll via Xib
set member properties to save pictures inside the cell
/** Picture Name * *
@property (nonatomic, copy) NSString *imagename;
Initializing cell
-(void) awakefromnib
{
//Layer set border
self.imageView.layer.borderColor = [Uicolor Whitecolor]. Cgcolor;
Self.imageView.layer.borderWidth = 6;
Self.imageView.layer.cornerRadius = 3;
}
To set the Image property of ImageView within a cell
-(void) Setimagename: (NSString *) imagename
{
_imagename = [imagename copy];
Self.imageView.image = [UIImage imagenamed:imagename];
}
Load Picture Resource
Save all picture names through member properties
/** All Pictures * * *
@property (nonatomic, strong) Nsmutablearray *imagenames;
Lazy load, initialize picture array group
-(Nsmutablearray *) imagenames
{
if (_imagenames = = nil)
{
Nsmutablearray *imagenames = [ Nsmutablearray array];
for (Nsinteger i = 0; i<20; i++)
{
NSString *imagename = [NSString stringwithformat:@ "%zd", i + 1];
[Imagenames addobject:imagename];
}
_imagenames = imagenames;
}
return _imagenames;
}
Create Uicollectionview
Save the Uicollectionview object through member properties to change the layout
@property (nonatomic, weak) Uicollectionview *collectionview;
Create and set CollectionView
-(void) Setupcollectionview
{
//Set frame
cgfloat collectionvieww = self.view.bounds.size.width;
CGFloat COLLECTIONVIEWH =;
CGRect frame = CGRectMake (0, COLLECTIONVIEWW, COLLECTIONVIEWH);
Create layout
Lypcirclelayout *layout = [[Lypcirclelayout alloc] init];
Create CollectionView
Uicollectionview *collectionview = [[Uicollectionview alloc] Initwithframe:frame Collectionviewlayout:layout];
Self.collectionview = CollectionView;
Sets the CollectionView data source and proxy
collectionview.datasource = self;
Collectionview.delegate = self;
Add CollectionView to the controller's view
[Self.view Addsubview:collectionview];
}
The method of realizing Uicollectionview data source
Register Cell
/** set reuse means
/static nsstring *const ID = @ "Photo";
-(void) viewdidload
{
[super viewdidload];
[Self setupcollectionview];
Registered cell
[Self.collectionview registernib:[uinib nibwithnibname:nsstringfromclass ([Lypphotocell class]) bundle : nil] forcellwithreuseidentifier:id];
}
Set the number of elements
-(Nsinteger) CollectionView: (nonnull uicollectionview *) CollectionView numberofitemsinsection: (NSInteger) Section
{return
self.imageNames.count;
}
Set properties for each element
-(Uicollectionviewcell *) CollectionView: (nonnull uicollectionview *) CollectionView Cellforitematindexpath: (nonnull Nsindexpath *) Indexpath
{
//Remove cell from cache pool according to reuse indication, if not in cache pool, automatically create
lypphotocell *cell = [CollectionView Dequeuereusablecellwithreuseidentifier:id Forindexpath:indexpath];
Set the ImageName property of the cell
cell.imagename = Self.imagenames[indexpath.item];
Returns the cell return
cell;
Implement Uicollectionview proxy method, realize click an element to delete its function
-(void) CollectionView: (nonnull uicollectionview *) CollectionView Didselectitematindexpath: (nonnull NSIndexPath *) Indexpath
{
//Remove the picture name from the array
[Self.imagenames RemoveObjectAtIndex:indexPath.item];
Deletes the element of the Indexpath position in the CollectionView
[Self.collectionview Deleteitemsatindexpaths:@[indexpath]];
Click on the Monitor controller view, replace the layout
-(void) Touchesbegan: (nonnull nsset<uitouch *> *) touches withevent: (Nullable uievent *) event
{
// Determine the type of current layout
if ([Self.collectionView.collectionViewLayout Iskindofclass:[lyplinelayout class]])
{
// Flow layout, switch to circular layout
[Self.collectionview setcollectionviewlayout:[[lypcirclelayout alloc] init] animated:yes];
} else
{
//circular layout, switch to flow layout
lyplinelayout *layout = [[Lyplinelayout alloc] init];
Set the dimensions of the element, and if not set, use the automatic calculation dimension
layout.itemsize = Cgsizemake (130, 130);
[Self.collectionview setcollectionviewlayout:layout animated:yes];
}
The above is the entire content of this article, I hope to help you learn.