Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 装饰图案、iOS/UICollectionViewCells出现问题_Iphone_Ios_Design Patterns_Decorator_Uicollectionview - Fatal编程技术网

Iphone 装饰图案、iOS/UICollectionViewCells出现问题

Iphone 装饰图案、iOS/UICollectionViewCells出现问题,iphone,ios,design-patterns,decorator,uicollectionview,Iphone,Ios,Design Patterns,Decorator,Uicollectionview,我正在尝试使用Decorator模式“装饰”UICollectionViewCells 例如,如果我有一个 BaseCell : UICollectionViewCell 我希望能够做到以下几点: BaseCell *cell = [[BaseCell alloc] initWithFrame] cell = [[GlowingCell alloc] initWithCell:cell]; cell = [[BorderedCell alloc] initWithCell:cell]

我正在尝试使用Decorator模式“装饰”UICollectionViewCells

例如,如果我有一个

 BaseCell : UICollectionViewCell 
我希望能够做到以下几点:

 BaseCell *cell = [[BaseCell alloc] initWithFrame]
 cell = [[GlowingCell alloc] initWithCell:cell];
 cell = [[BorderedCell alloc] initWithCell:cell];
 cell = [[LabelledCell alloc] initWithCell:cell];

 // cell is now a glowing, bordered, labelled cell.
 [self.collectionView registerClass:cellClass forCellWithReuseIdentifier:cellIdentifier];
我认为Decorator模式对于这类东西来说是非常整洁的,但是我很难将它应用到集合视图中

首先,在UICollectionViewController中,您需要注册一个类,如下所示:

 BaseCell *cell = [[BaseCell alloc] initWithFrame]
 cell = [[GlowingCell alloc] initWithCell:cell];
 cell = [[BorderedCell alloc] initWithCell:cell];
 cell = [[LabelledCell alloc] initWithCell:cell];

 // cell is now a glowing, bordered, labelled cell.
 [self.collectionView registerClass:cellClass forCellWithReuseIdentifier:cellIdentifier];
所以我没有机会提出我自己的例子

其次,我看不出Decorator在装饰“非纯”对象方面有什么用处,也就是说,我不是从头开始创建的对象,但它们有自己的属性和行为(例如UICollectionViewCell)。因为在上面的示例中,
cell
表示LabelledCell的一个新实例,如果UICollectionView调用一个方法,例如,
isSelected
,这将调用
aLabelledCellInstance.isSelected
,除非我在我的装饰器基类中特别这样做:

 - (BOOL)isSelected {
      return self.decoratedCell.isSelected;
 }
这对于一个方法来说很好,但是必须重写
UICollectionViewCell
中的每个方法似乎并不正确。我应该使用
转发调用:

我是否滥用了这种模式,还有其他选择吗?因为它在书中非常好地工作,当你只需要覆盖基本方法时,比如

 getPrice() {
      return decoratedObject.getPrice() + 1.10f;
 }
。。但似乎很难达到用自定义行为装饰现有UI元素的目的

谢谢

编辑:我试图避免的是这样的课程:

 BaseCell *cell = [[BaseCell alloc] initWithFrame]
 cell = [[GlowingCell alloc] initWithCell:cell];
 cell = [[BorderedCell alloc] initWithCell:cell];
 cell = [[LabelledCell alloc] initWithCell:cell];

 // cell is now a glowing, bordered, labelled cell.
 [self.collectionView registerClass:cellClass forCellWithReuseIdentifier:cellIdentifier];
  • 发光边界细胞
  • 带标签的带边框单元格
  • 等等

从理论上讲,Decorator是我试图实现的完美候选对象,但其实现绝对让我难堪。

首先,Decorator模式要求您覆盖
BaseDecorator
中的所有基本方法,以便将调用转发给Decorator对象。 您可以通过覆盖每一个方法来实现这一点,或者最好只使用
forwardInvocation:
。由于所有其他装饰器都将是
BaseDecorator
的子类,因此现在您可以覆盖您想要更改的方法

其次,对于
CollectionView
问题,我建议将Decorator模式与普通
UIView
s一起使用,然后将修饰后的视图用作单元格的
contentView
。 让我们看一个例子:

我们有
BaseCellView
类,它将是所有decorator的超级类

BaseCellView : UIView;
GlowingCellView: BaseCellView;
BorderedCell: BaseCellView;
LabelledCell: BaseCellView;
我们还有
BaseCell
类,它是
UICollectionViewCell
的子类:

BaseCell : UICollectionViewCell;
现在,
UICollectionViewControllers
将始终创建
BaseCell
的实例,并为您提供配置它的机会,您将在其中执行以下操作:

BaseCellView *cellView = [[BaseCellView alloc] initWithFrame]
cellView = [[GlowingCellView alloc] initWithCellView:cellView];
cellView = [[BorderedCellView alloc] initWithCellView:cellView];
cellView = [[LabelledCellView alloc] initWithCellView:cellView];
cell.contentView = cellView;
如果您愿意,您仍然可以将任何
UICollectionViewCell
转发给装饰师。

这篇文章中我介绍了这种技术。虽然我选择装饰
UITableView
而不是单元格,但它可以很容易地适应您的收藏视图。这是一本相当长的书,所以我在这里只做一个简短的总结:

  • 装饰器需要是代理对象才能将所有消息转发到装饰对象
  • 要实现这一点,您需要在装饰器中重写多种方法,其中
    respondsToSelector
    forwardingTargetForSelector
  • 完成后,您将能够链接装饰师,这非常整洁:
e、 g:


这是一个有趣的问题,我喜欢将其应用于UI项的想法。从实现的角度来看,您怀疑是否滥用了模式,这实际上取决于可读性和可维护性。如果使用这种模式(即使覆盖了很多方法)使代码更可读和可维护,那么就这样做。如果它模糊了代码的意图和功能,使下一个家伙更难更改代码,那么不要认为这是它的主要用途之一。@Rob,我理解设计模式的目的,但在Sam的情况下,他必须做额外的、可能不太可维护的工作才能使解决方案正常工作。我试图给Sam一个基本上是callI没有批评的判断的基础,我只是说,Decorator最常用于ui的东西,就像他问的那样。必须委托所有的方法似乎是一个阻力,尽管你可以做一些杂注和代码折叠。这就是装饰工的工作原理。我曾经想过这样的想法,我认为它们很好。所以你不能注册你自己的班级?怎么样?这不是他们要求实例化类的全部目的吗?这就是我喜欢StackOverflow的原因。回答得好,我要试试这个。谢谢接受这一点作为答案,我最终没有使用此模式,因为我需要在创建后访问各种单元格属性,并且不想将它们全部包含在基本装饰器界面中-我现在只坚持更严格的设计。我认为您可以将指向
单元格的指针传递给
CellView
的初始值设定项,因此,每个
CellView
都可以访问它所修饰的单元格的属性。但你可能会开始觉得它变成了一个黑客的解决方案。不仅如此,在configureCell上分配所有的装饰视图而不是重用,都是次优的