草庐IT

ios: UITableVIewCell 扩展未按预期工作

coder 2024-01-18 原文

我的 TableView 单元格有一个按钮。单击时,我想展开单元格。为了展开,我在单击按钮时更改单元格的高度并重新加载该行。但是当展开一行然后我尝试展开另一行时,行为并不像预期的那样。关闭之前展开的行而不是单击的行。

此外,有时我必须点击按钮两次才能展开。

public class ProgramMeasurementDetailsTableViewSource : UITableViewSource
{

    List<ProgramMeasurementDetail> mList;

    string HeaderIdentfier = "programMeasurementDetailsHeader";
    string CellIdentifier = "programMeasurementDetailsCell";
    int TAG_CHECKBOX = 61;
    int TAG_LABEL_VITAL_NAME = 62;
    int TAG_LABEL_GOAL = 63;
    int TAG_BUTTON_EDIT = 64;
    int TAG_VIEW_HEADER_COLUMN_SEPARATOR = 66;
    int TAG_VIEW_ROW_COLUMN_SEPARATOR = 65;
    List<bool> expandStatusList = new List<bool>();
    UITableView tableView;

    public ProgramMeasurementDetailsTableViewSource(List<ProgramMeasurementDetail> mList, UITableView tableView)
    {
        this.tableView = tableView;
        this.mList = mList;
        for (int i = 0; i < mList.Count; i++)
            expandStatusList.Add(false);
    }

    public override nint NumberOfSections(UITableView tableView)
    {
        return 1;
    }

    public override nint RowsInSection(UITableView tableview, nint section)
    {
        return mList.Count;
    }

    public override nfloat GetHeightForHeader(UITableView tableView, nint section)
    {
        return 32;
    }

    public override nfloat GetHeightForRow(UITableView tableView, Foundation.NSIndexPath indexPath)
    {
        if (expandStatusList[indexPath.Row])
            return 70;
        else
            return 32;
    }

    public override UITableViewCell GetCell(UITableView tableView, Foundation.NSIndexPath indexPath)
    {
        UITableViewCell cell = tableView.DequeueReusableCell(CellIdentifier);
        if (cell == null)
        {
            cell = new UITableViewCell(UITableViewCellStyle.Default, CellIdentifier);
        }
        CheckBox checkBox = (CheckBox)cell.ViewWithTag(TAG_CHECKBOX);
        UILabel vitalNameLabel = (UILabel)cell.ViewWithTag(TAG_LABEL_VITAL_NAME);
        UILabel goalLabel = (UILabel)cell.ViewWithTag(TAG_LABEL_GOAL);
        UIButton editGoalButton = (UIButton)cell.ViewWithTag(TAG_BUTTON_EDIT);
        editGoalButton.TouchUpInside += (object sender, EventArgs e) =>
         {
             expandStatusList[indexPath.Row] = !expandStatusList[indexPath.Row];
             tableView.ReloadRows(new Foundation.NSIndexPath[] { indexPath }, UITableViewRowAnimation.Automatic);

         };

        .....
        return cell;
    }
}

我尝试在 if (cell == null) 中移动按钮单击事件处理,但按钮单击/展开根本不起作用。我放置了断点,似乎该部分从未执行过。

我在 Storyboard中设计了单元格布局。

我已经为这个问题苦苦挣扎了一段时间。感谢您的帮助。

最佳答案

当您上下滚动列表时,是否会出现您看到的错误?发生这种情况是因为您在 GetCell 方法中连接了 TouchUpInside 事件处理程序,然后在重复使用该单元格时它永远不会脱钩,因此您最终连接了多个单元格到同一个处理程序甚至多个处理程序!

通常,您不想在 GetCell 方法中对事物执行这些类型,它应该只用于 DequeueReusableCell 或创建一个新的。其他一切都应该在自定义单元格中完成。

查看您的代码示例,您似乎没有使用自定义单元格,因此您可以这样做:

1.) 在 GetCell 中将按钮的标签设置为 IndexPath 的行

editGoalButton.Tag = indexPath.Row;

2.) 在 ProgramMeasurementDetailsTableViewSource 中为您的事件处理程序创建一个单独的方法:

private void ToggleRow(object sender, EventArgs e)
{
    var btn = sender as UIButton;
    expandStatusList[btn.Tag] = !expandStatusList[btn.Tag];
    tableView.ReloadRows(new Foundation.NSIndexPath[] { NSIndexPath.FromRowSection(btn.Tag, 0) }, UITableViewRowAnimation.Automatic);
}

3.) 在 GetCell 中,在重新挂接 TouchUpInside 处理程序之前取消挂接:

editGoalButton.TouchUpInside -= ToggleRow;
editGoalButton.TouchUpInside += ToggleRow;

虽然这将确保按钮只连接一次,但它确实不是处理这种情况的正确方法。您应该使用自定义单元格并在单元格中进行所有布线,然后在 UITableViewCell 中的 PrepareForReuse 覆盖中取消 Hook 并进行清理。我强烈建议您通过这个 Xamarin tutorial

如果您确实了解了它...请注意 GetCell 方法的整合程度。

--更新-- 在您的 CustomCell 类中:

private EventHandler _tapAction;
public void Setup(EventHandler tapAction, int row, ....)
{
     //keep a reference to the action, so we can unhook it later
     _tapAction = tapAction;
     editGoalButton.Tag = row;
     ....
     editGoalButton.TouchUpInside += _tapAction;
}

public override void PrepareForReuse()
{
     ....
     editGoalButton.TouchUpInside -= _tapAction;
     _tapAction = null;
}

当您在 GetCell 中调用 Setup 时,您只需将 ToggleRow 方法作为 Action 参数传递即可。

关于ios: UITableVIewCell 扩展未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38961804/

有关ios: UITableVIewCell 扩展未按预期工作的更多相关文章

  1. ruby-on-rails - 由于 "wkhtmltopdf",PDFKIT 显然无法正常工作 - 2

    我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-

  2. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  3. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  4. ruby - 无法让 RSpec 工作—— 'require' : cannot load such file - 2

    我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳

  5. ruby-on-rails - rspec should have_select ('cars' , :options => ['volvo' , 'saab' ] 不工作 - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request

  6. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

    在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

  7. ruby - 如何验证 IO.copy_stream 是否成功 - 2

    这里有一个很好的答案解释了如何在Ruby中下载文件而不将其加载到内存中:https://stackoverflow.com/a/29743394/4852737require'open-uri'download=open('http://example.com/image.png')IO.copy_stream(download,'~/image.png')我如何验证下载文件的IO.copy_stream调用是否真的成功——这意味着下载的文件与我打算下载的文件完全相同,而不是下载一半的损坏文件?documentation说IO.copy_stream返回它复制的字节数,但是当我还没有下

  8. Ruby 文件 IO 定界符? - 2

    我正在尝试解析一个文本文件,该文件每行包含可变数量的单词和数字,如下所示:foo4.500bar3.001.33foobar如何读取由空格而不是换行符分隔的文件?有什么方法可以设置File("file.txt").foreach方法以使用空格而不是换行符作为分隔符? 最佳答案 接受的答案将slurp文件,这可能是大文本文件的问题。更好的解决方案是IO.foreach.它是惯用的,将按字符流式传输文件:File.foreach(filename,""){|string|putsstring}包含“thisisanexample”结果的

  9. c - mkmf 在编译 C 扩展时忽略子文件夹中的文件 - 2

    我想这样组织C源代码:+/||___+ext||||___+native_extension||||___+lib||||||___(Sourcefilesarekeptinhere-maycontainsub-folders)||||___native_extension.c||___native_extension.h||___extconf.rb||___+lib||||___(Rubysourcecode)||___Rakefile我无法使此设置与mkmf一起正常工作。native_extension/lib中的文件(包含在native_extension.c中)将被完全忽略。

  10. ruby - JetBrains RubyMine 3.2.4 调试器不工作 - 2

    使用Ruby1.9.2运行IDE提示说需要gemruby​​-debug-base19x并提供安装它。但是,在尝试安装它时会显示消息Failedtoinstallgems.Followinggemswerenotinstalled:C:/ProgramFiles(x86)/JetBrains/RubyMine3.2.4/rb/gems/ruby-debug-base19x-0.11.30.pre2.gem:Errorinstallingruby-debug-base19x-0.11.30.pre2.gem:The'linecache19'nativegemrequiresinstall

随机推荐