C# 使用两个相似的集合视图单元格,从而避免代码重复
我想要两个几乎相似的细胞。区别仅在于在其上显示多个视图 因此,我想使用自定义构造函数。通常,您有一个与此类似的构造函数:C# 使用两个相似的集合视图单元格,从而避免代码重复,c#,ios,xamarin,xamarin.ios,uicollectionviewcell,C#,Ios,Xamarin,Xamarin.ios,Uicollectionviewcell,我想要两个几乎相似的细胞。区别仅在于在其上显示多个视图 因此,我想使用自定义构造函数。通常,您有一个与此类似的构造函数: public class AnimalCell : UICollectionViewCell { [Export ("initWithFrame:")] public AnimalCell (CGRect frame) : base (frame) { // do something } } 我想传递一个类型,根据该类型,我想
public class AnimalCell : UICollectionViewCell
{
[Export ("initWithFrame:")]
public AnimalCell (CGRect frame) : base (frame)
{
// do something
}
}
我想传递一个类型,根据该类型,我想在单元格上显示不同的项目。最好的方法是使用如下构造函数:
public AnimalCell(MyCustomType type)
{
if(type == XXX){
// add as subview, add constraints, ...
}else{
// normal setup
}
}
我当然想保持细胞的重复使用。这能实现吗?怎么做
我想到的另一件事是使用子类化。有人知道我如何定义单元格,这样我就不必重复相同的代码了吗?例如
var cell = null;
if (MyCustomType == XXX) {
cell = collectionView.DequeueReusableCell (DefaultCell.Key, indexPath) as DefaultCell;
} else {
cell = collectionView.DequeueReusableCell (CustomizedCell.Key, indexPath) as CustomizedCell;
}
cell.DoSomething("someValue"); // this doesn't work because you have to define cell with a certain class
// do some more initialization
我当前的解决方案:
public abstract class DefaultCell : UICollectionViewCell
{
protected bool someVariable;
[Export ("initWithFrame:")]
public DefaultCell (CGRect frame) : base (frame)
{
}
public void DoSomething(string text)
{
label.Text = text;
}
}
public class Custom1Cell : DefaultCell
{
public static readonly NSString Key = new NSString ("Custom1Cell");
[Export ("initWithFrame:")]
public Custom1Cell (CGRect frame) : base (frame)
{
initialize ();
}
private void initialize()
{
// some initialization
}
}
public class Custom2Cell : DefaultCell
{
public static readonly NSString Key = new NSString ("Custom2Cell");
[Export ("initWithFrame:")]
public Custom2Cell (CGRect frame) : base (frame)
{
initialize ();
}
private void initialize()
{
// some initialization
}
public void SomeMethod(string text)
{
if(someVariable)
someOtherLabel.Text = text;
}
}
如马哈茂德所述,排队工作如下:
DefaultCell cell;
if (type = XXX) {
cell = collectionView.DequeueReusableCell (Custom1Cell.Key, indexPath) as Custom1Cell;
} else {
cell = collectionView.DequeueReusableCell (Custom2Cell.Key, indexPath) as Custom2Cell;
}
cell.DoSomething("works on both cell types");
((Custom2Cell)cell).SomeMethod("works only on one cell type");
您可以添加UICollectionViewCell的子类,比如说YourCell。现在将您的单元格交给故事板中的单元格。在YourCell中,您可以添加任意数量的视图,您可以将它们从故事板单元输出到YourCell类,然后您可以根据需要自定义视图 更新: 好吧,假设你没有在故事板中添加这个视图,但是你把它作为一个属性(我只是一个指针,所以不会占用很多内存:)只需要在getter上进行惰性实例化,并用这个getter方法设置它的约束。下面是一个惰性实例化的示例,我们有一个不在故事板视图中的标签
-(UILabel *)yourLabel
{
if(!_yourLabel){
_yourLabel=[[UILabel alloc]init];
NSLayoutConstraint *leadingConstraint= [NSLayoutConstraint constraintWithItem:self.contentView attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:_yourLabel attribute:NSLayoutAttributeLeading multiplier:1.0 constant:0];
NSLayoutConstraint *topConstraint= [NSLayoutConstraint constraintWithItem:self.contentView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:_yourLabel attribute:NSLayoutAttributeTop multiplier:1.0 constant:0];
[self.contentView addConstraints:@[leadingConstraint,topConstraint]];
}
return _yourLabel;
}
您可能会考虑一个抽象类,该类具有共享变量和方法(命名为BaseClass)和其他两个继承抽象类的类,在代码中可以将单元格定义为对象并在IF语句中初始化它,如下所示:
Object cell;
if (MyCustomType == XXX) {
cell = new class1()
((Class1) cell).MethodInClass1();
} else{
cell = new class2();
((Class2) cell).MethodInClass2();
}
是的,我可以在我的手机上放置一个视图并隐藏它(但它总是会被创建并消耗一些性能/内存)。另一件事是使用添加视图并重新排列所有约束的方法。我正在寻找一种更通用的解决方案,它将使问题变得清晰和简单(例如,当存在更多差异时)。但总的来说你是对的。我已经更新了我的答案。对不起,我不太了解斯威夫特。我希望你明白了。啊,好的,我明白了。我的代码不是Swift btw(它是C#)格式的,但这并不重要。当然,如果您愿意,您可以发布Objective-C/Swift:)对于我的情况,您的解决方案将有效+1如果我必须对结构进行更大的更改,我还必须重新排列所有其他视图和约束。因此,我现在尝试使用一个抽象类。听起来很合理。现在我试过了。我缺少一件事:我已经定义了抽象类对象。如何在class2上调用
cell.DoSomething()
?因为DoSomething只在class2中定义,而不是在抽象类中定义。Object是java类型,而不是抽象类。您可以使用名称BaseClass将抽象类命名为,正如我在中提到的,如果您可以从calss1或class2实例化它。当您想要调用只属于类2的方法DoSomthing时,必须执行以下操作((Class2)cell);此外,我还编辑了关于这些评论的答案!!!