我可以“拿出来”吗?或“撕掉”或来自UICollectionView的单元格? [英] Can I "take out" or "tear off" a cell from a UICollectionView?

查看:67
本文介绍了我可以“拿出来”吗?或“撕掉”或来自UICollectionView的单元格?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意 - 可能是UIViewControllerAnimatedTransitioning



https://developer.apple.com/library/ios/documentation/uikit/reference/UIViewControllerAnimatedTransitioning_Protocol/Reference/Reference.html



与此相关。



注意 - 我刚刚意识到新的iOS7轻扫手势就是这个概念



这里有一些答案:



UICollectionViewswipe-away在iOS7应用管理器中?






想象一下,你的iPad有一个垂直的UICollectionView(bigView),包含10个细胞,每个细胞约400x400。想象一下,bigView位于屏幕的右半部分,比如说。



我想这样做:



也许点击了3号单元格。



该单元格远离集合视图(例如,移动到屏幕左侧)。 TBC它移动到UICollectionView的边界之外。理想情况下它变成了正常的UIView(比方说)。



事实上,我想:



(1)销毁其他9个单元格



(2)完全销毁UICollectionView



(3)实际上,转换为一个单元格,#3,到(我猜)一个UIView



我会从那里拿走它!



这可以吗?



(a)你能转换UICollectionViewCell到UIView (它有UIView胆量可以删除??)



(b)你是否(或许)可以销毁所有其他单元格,让UICollectionView确实只是那个单元格(并且可能会移动整个单元格)事情)...



(c)是否有来自UICollectionView的任何其他类型的撕下机制






现在已经工作了很多次,这是最简单的基本解决方案。



你将拥有一个字面上是集合视图的类,

  @interface BouncyItems:UICollectionViewController 

在该类中你将有一个didSelectItemAtIndexPath:或类似的:



在那里,你可以很容易地找到有问题的单元格。

   - (void)collectionView:(UICollectionView * )cv 
didSelectItemAtIndexP ath:(NSIndexPath *)indexPath
{
NSInteger thisRow = indexPath.row;
NSString * thatName = yourData.stuff [thisRow] [@nameField];
YourCellClass * cell = [cv cellForItemAtIndexPath:indexPath];

NSLog(@Yo,剥离.......%@%@,名称);

YourScene * parent =(YourScene *)self.parentViewController;
[parent peelOff:cell.holder];
}

但更重要的是,你将拥有一个真实的场景,一个容器视图,它是集合视图。



因此在示例中,YourScene是UIViewController,它确实有一些容器视图。其中一个容器视图确实是有问题的集合视图。

  @interface YourScene:UIViewController 
@property(nonatomic ,strong)IBOutlet UIView * bouncyItemsContainer;
- (void)peelOff:(UIView *)peelMe;
@end

请注意,在故事板中,看着你的BouncyItems,你会被拖回去从它到bouncyItemsContainer的连接



(与你将YourScene中的按钮挂钩到相关IBOutlet项目的方式没什么不同。)



因此,查看didSelectItemAtIndexPath中的代码,就这么简单,

  YourScene * parent =(YourScene *)self.parentViewController; 
[parent peelOff:cell.holder];

什么是.holder..解释如下。



现在什么是例程peelOff?令人惊讶的是,这很简单。



秘诀就是convertPoint:代码行......



   - (void)peelOff:(UIView *)peelMe 
{
CGPoint oldCenter = [self.view
convertPoint:peel.center
fromView:peel .superview];
[self.view addSubview:peelMe];
peelMe.center = oldCenter;
[self.bouncyItemsContainer exitLeft];
}

{回想 addSubview:方便地从它的旧超级视图中删除视图,因此它可以在一行代码中完成所有这些操作。}



所以,就是这样 - 前三行代码,您已从容器视图中删除了一个单元格peelMe。它现在只是正常场景的一部分,YourScene。



接下来,简单地摆脱集合视图。在我的例子中,exitLeft只是将它从屏幕左侧动画化。



所以,它是完美的 - 你点击一个单元格;所有其余的收集视图都会在屏幕上显示动画(你可以在那里做任何你想做的事情,让它们飞走,面朝外,翻滚 - 无论如何),并选择一个细胞留在后面。由于神奇的convertPoint代码行,所有内容都保持正确。



最后所有单元格必须有一个.holder,即..... / p>



一个UIView,它包含单元格中的所有内容;这就是你剥离的东西。 (这是唯一实用的解决方案,不要取出单元格的底层.contentView。)你可以仔细安排白色/清晰等背景,这样如果你在场景中飞来飞去,一切都正常。 / p>

所以,这就是它的全部。



你现在有(1)摆脱了集合视图,(2)你的YourScene拥有的是一个单元格。



所以,在peelOff中:你会通过.holder UIVIew,你可能也会传递你的一些数据,如用户选择了这个房子来查看内部或任何你的上下文。



最后在最初的问题中,它提到了然后将去皮视图移动到YourScene上的某个位置。当然,只要你想要它就可以动画它,可能是在peelOff :.



希望它有所帮助。

解决方案

我已经按照这些方针做了些什么。我已经实现了在集合视图和部分之间拖动单元格。我还需要一个外部目标到集合视图来拖动单元格。我只是关闭了collectionView图层上的masksToBounds,我能够将我的假浮动单元(代表真实的隐藏单元格)拖到集合视图的边界之外。



无论如何,我认为基本上隐藏在你的例子中没有聚焦的单元格会更容易,并根据需要为焦点单元格设置动画。



考虑实现 - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath 在您的集合视图布局上。您可以重新布局您的collectionView以移动/调整聚焦单元格的大小,以及将已毁坏单元格的框架设置为屏幕外,更小或以其他方式修改。



您还可以设置这些布局更改的动画,甚至可以在布局之间移动,这可以实现非常漂亮的过渡。



没有理由集合视图中的一个单元格不能很好大而且与所有其他细胞的框架非常不同。如果我这样做,我可能会将正常细胞保留在一个区域中,而聚焦细胞作为另一个区域中的唯一细胞(因为在区域之间移动细胞是微不足道的)。然后,使用上面的方法,我可以更容易地将单元格的布局主题化,因为我可以按部分引用项目。


Note - it's possible UIViewControllerAnimatedTransitioning

https://developer.apple.com/library/ios/documentation/uikit/reference/UIViewControllerAnimatedTransitioning_Protocol/Reference/Reference.html

is relevant here.

Note - I've just realised the new iOS7 "swipe-away" gesture is this concept

there are some answers HERE:

The UICollectionView "swipe-away" in iOS7 app manager?


Imagine your iPad has a UICollectionView ("bigView"), vertical, which contains 10 cells, each about 400x400 say. Imagine the bigView is on the right half of the screen, say.

I want to do this:

Cell number 3 is perhaps clicked.

That cell moves away from the collection view (say, to the left of the screen). TBC it moves outside the boundary of the UICollectionView. Ideally it becomes a normal UIView (say).

In fact, I want to:

(1) destroy the other 9 cells

(2) destroy entirely the UICollectionView

(3) in fact, convert the one cell, #3, to (I guess) a UIView

I'll take it from there!

Can this be done??

(a) can you "convert" a UICollectionViewCell to a UIView (does it have a UIView guts you can "remove" ??)

(b) can you (perhaps) destroy all of the other cells, leaving the UICollectionView as, indeed, really being only that one cell (and perhaps move the "whole thing") ...

(c) is there any other sort of "tear off" mechanism from a UICollectionView?


Having worked on this many, many times now, here's pretty much the simplest basic solution.

You'll have a class that is literally the collection view,

@interface BouncyItems : UICollectionViewController

in that class you'll have a didSelectItemAtIndexPath: or similar:

in there, you can easily get at the cell in question.

-(void)collectionView:(UICollectionView *)cv
  didSelectItemAtIndexPath:(NSIndexPath *)indexPath
    {
    NSInteger thisRow = indexPath.row;
    NSString *thatName = yourData.stuff[thisRow][@"nameField"];
    YourCellClass *cell = [cv cellForItemAtIndexPath:indexPath];

    NSLog(@"Yo, peeling off ....... %@  %@", theName);

    YourScene *parent = (YourScene *)self.parentViewController;
    [parent peelOff:cell.holder];
    }

But more importantly, you're going to have an actual scene, that has a container view, which is the collection view.

So in the example, "YourScene" is the UIViewController, which indeed has a few container views. One of those container views is indeed the collection view in question.

@interface YourScene:UIViewController
@property (nonatomic, strong) IBOutlet UIView *bouncyItemsContainer;
-(void)peelOff:(UIView *)peelMe;
@end

Note that in storyboard, looking at your BouncyItems, you would have dragged back the connection from it to "bouncyItemsContainer"

(No different than how you'd hook up buttons in "YourScene" to the relevant IBOutlet items.)

So, looking at the code in didSelectItemAtIndexPath, it's this easy,

    YourScene *parent = (YourScene *)self.parentViewController;
    [parent peelOff:cell.holder];

What is ".holder" .. explained below.

Now what is the routine peelOff ? Amazingly it's this simple.

The secret sauce is the convertPoint: line of code...

-(void)peelOff:(UIView *)peelMe
    {
    CGPoint oldCenter = [self.view
      convertPoint:peel.center
      fromView:peel.superview];
    [self.view addSubview:peelMe];
    peelMe.center = oldCenter;
    [self.bouncyItemsContainer exitLeft];
    }

{Recall that addSubview: conveniently removes the view from it's old superview, so it does all that for you in one line of code.}

So, that's it - the first three lines of code, you've removed the one cell, peelMe, from the container view. It is now just part of the normal scene, YourScene.

Next, simply "get rid of" the collection view. In my example, exitLeft simply animates it off the screen to the left.

So, it's perfect - you click on one cell; all the rest of the collection view animates off the screen (you could do whatever you want there, make them "fly off", face out, tumble - whatever), and the one chosen cell remains behind. Due to the "magic" convertPoint line of code, everything stays correctly in place.

Finally all cells must have a ".holder" which is.....

a UIView that holds everything in the cell; that's what you peel off. (This is the only practical solution, don't take out the underlying .contentView of the cell.) You can carefully arrange white/clear etc backgrounds so that everything "works" properly if you're flying stuff around in the scene.

So, that's all there is to it.

You now have (1) got rid of the collection view, and (2) your YourScene owns the thing that was a cell.

So, in peelOff: you would pass through the .holder UIVIew, and, you would probably also pass through some of your data, as in "the user has selected this house to see the interior" or whatever your context is.

Finally in the original question, it mentions then moving the peeled view, to some position on the YourScene. Of course, just animate it whether you want, probably in peelOff:.

Hope it helps.

解决方案

I've done something along these lines. I've implemented dragging of cells around the collection view and between sections. I also needed an 'external target' to the collection view to drag cells onto. I simply turned off masksToBounds on the collectionView's layer, and I was able to drag my fake floating cell (representing the real, hidden cell) beyond the bounds of the collection view.

Regardless, I think it's much easier to basically hide the cells that are not "focused" in your example, and animate out the changes for the focussed cell as needed.

Consider implementing - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect and - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath on your collection view layout/s. You can both relayout your collectionView to move/resize the focussed cell, as well as setting the frame of the "destroyed" cells to off screen, smaller, or otherwise modified.

You can also animate these layout changes, or even move between layouts, which can make for very nifty transitions.

There is no reason one cell in the collectionView cannot be very large and have a very different frame than all the other cells. If I were to do this, I might keep the normal cells in one section, and the focussed cell as the only cell in another (as it's trivial to move cells between sections). Then, using the above methods, I'd have an easier time theming the layout for the cells en masse, as I could refer the the items by section.

这篇关于我可以“拿出来”吗?或“撕掉”或来自UICollectionView的单元格?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆