Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.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
C# 使用两个相似的集合视图单元格,从而避免代码重复_C#_Ios_Xamarin_Xamarin.ios_Uicollectionviewcell - Fatal编程技术网

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);此外,我还编辑了关于这些评论的答案!!!