仅触发UITableViewCell中的最后一个UISwitch

时间:2013-02-10 14:15:26

标签: xamarin.ios

我试图在每个单元格中添加一个UISwitch(这是有效的)。当我点击切换除最后一个之外的任何开关时,它们都会给出最后一个开关状态,直到我改变最后一个开关状态

        `public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath) {
            //---- declare vars
            UITableViewCell cell = tableView.DequeueReusableCell (this._cellIdentifier);

            //---- if there are no cells to reuse, create a new one
            if (cell == null) {
                // This changes the style of the UITableViewCell to the Default style
                cell = new UITableViewCell (UITableViewCellStyle.Default, this._cellIdentifier);

                // Instantiate a cell accessory here
                uiSwitch = new UISwitch (new RectangleF (0f, 0f, 20f, 20f));
                uiSwitch.Tag = indexPath.Row;
                uiSwitch.ValueChanged += (object sender, EventArgs e) => {
                    Console.WriteLine ("Cell Switch value is now {0}", uiSwitch.On);
                };
                _vRMs.View.AddSubview (uiSwitch);

                // keep a reference to each cell you create,
                //  e.g. add them to a static List<UITableViewCell>.
                //  The GC won't be able to collect them so the event handler will work later.
                cells.Add (cell);
            }

            //---- create a shortcut to our item
            TableViewItem item = this._TableViewItemGroupList[indexPath.Section].Items[indexPath.Row];

            cell.TextLabel.Text = item.Name;
            cell.Accessory = UITableViewCellAccessory.DisclosureIndicator;
            cell.AccessoryView = uiSwitch;
            // cell.DetailTextLabel.Text = item.SubHeading;


            return cell;
        }`

我想知道是否所有这些代码都是用UISwitches创建一个表所必需的 - 对于iPhone开发世界来说是新手,我不确定。 我希望这次更新对我的事业有所帮助。

`using System;
using System.Drawing;
using System.Collections.Generic;

using MonoTouch.Foundation;
using MonoTouch.UIKit;

namespace eOneRaw {
    public partial class vRMs : UIViewController {

        #region FIELDS
        private string _ViewTitle = "RMs";
        private UITableView _TableView;
        private TableViewDataSource _TableViewDataSource;
        private List<TableViewItemGroup> _TableViewItemGroupList;
        private static vRMs _vRMs;
        #endregion      

        #region PROPERTIES
#endregion

        #region ViewDidLoad
        public override void ViewDidLoad () {
            base.ViewDidLoad ();

            // Title the Controller
            Title = _ViewTitle;

            #region UITableView Setup
            // Set up the table and data
            this.CreateTableItems ();

            // Create the UITableView
            _TableView = new UITableView() {
                Delegate = new TableViewDelegate(_TableViewItemGroupList),
                DataSource = _TableViewDataSource,
                AutoresizingMask = UIViewAutoresizing.FlexibleHeight | UIViewAutoresizing.FlexibleWidth,
            };

            _TableView.SizeToFit();

            // Reposition and resize the receiver
            _TableView.Frame = new RectangleF (0, 0, this.View.Frame.Width, this.View.Frame.Height);

            // Add the table view as a subview
            this.View.AddSubview(_TableView);
#endregion

            #region Define the Look of the View
            var _barbtnCancel = new UIBarButtonItem(UIBarButtonSystemItem.Done);
            NavigationItem.LeftBarButtonItem = _barbtnCancel;

            _barbtnCancel.Clicked += (s, e) => {
                this.NavigationController.PopViewControllerAnimated(true);
            };
#endregion

        } // end ViewDidLoad
#endregion

        #region METHODS
        public vRMs () {
            // Shouldn't ever happen
            _vRMs = this;
            Console.WriteLine (Environment.StackTrace);
        }

        public override void DidReceiveMemoryWarning () {
            // Releases the view if it doesn't have a superview.
            base.DidReceiveMemoryWarning ();

            // Release any cached data, images, etc that aren't in use.
        }
#endregion

        #region ALL TABLE FUNCTIONALITY

        #region CreateTableItems
        //========================================================================
        /// <summary>
        /// Creates a set of table items.
        /// </summary>
        // This is where you define your table
        protected void CreateTableItems () {
            _TableViewItemGroupList = new List<TableViewItemGroup> ();

            //---- declare vars
            TableViewItemGroup tGroup;

            tGroup = new TableViewItemGroup() { Name = "Regional Managers" };
            tGroup.Items.Add (new TableViewItem() { Name = "Chris" });
            tGroup.Items.Add (new TableViewItem() { Name = "Mike" });
            tGroup.Items.Add (new TableViewItem() { Name = "Dan" });
            tGroup.Items.Add (new TableViewItem() { Name = "Steve" });
            _TableViewItemGroupList.Add (tGroup);

            this._TableViewDataSource = new TableViewDataSource(_TableViewItemGroupList);
        }
#endregion

        #region CLASS TableViewDelegate
        // The delegate manages the transitions from view-to-view
        private class TableViewDelegate : UITableViewDelegate {
            private List<TableViewItemGroup> _TableViewItemGroupList;

            public TableViewDelegate(List<TableViewItemGroup> pList) {
                this._TableViewItemGroupList = pList;
            }

            public override void RowSelected (UITableView tableView, NSIndexPath indexPath) {
                return;
            }
        }
#endregion

        #region CLASS TableViewDataSource
        public class TableViewDataSource : UITableViewDataSource {

            protected List<TableViewItemGroup> _TableViewItemGroupList;
            string _cellIdentifier = "TableViewCell";
            private static UISwitch uiSwitch;
            static List<UITableViewCell> cells = new List<UITableViewCell> ();

            public TableViewDataSource (List<TableViewItemGroup> items) {
                this._TableViewItemGroupList = items;
            }

            /// <summary>
            /// Called by the TableView to determine how many sections(groups) there are.
            /// </summary>
            public override int NumberOfSections (UITableView tableView) {
                return this._TableViewItemGroupList.Count;
            }

            /// <summary>
            /// Called by the TableView to determine how many cells to create for that particular section.
            /// </summary>
            public override int RowsInSection (UITableView tableview, int section) {
                return this._TableViewItemGroupList[section].Items.Count;
            }

            /// <summary>
            /// Called by the TableView to retrieve the header text for the particular section(group)
            /// </summary>
            public override string TitleForHeader (UITableView tableView, int section) {
                return this._TableViewItemGroupList[section].Name;
            }

            /// <summary>
            /// Called by the TableView to retrieve the footer text for the particular section(group)
            /// </summary>
            public override string TitleForFooter (UITableView tableView, int section) {
                return this._TableViewItemGroupList[section].Footer;
            }

            #region UITableViewCell
            /// <summary>
            /// Called by the TableView to get the actual UITableViewCell to render for the particular section and row
            /// </summary>
            public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath) {
                //---- declare vars
                UITableViewCell cell = tableView.DequeueReusableCell (this._cellIdentifier);

                //---- if there are no cells to reuse, create a new one
                if (cell == null) {
                    // This changes the style of the UITableViewCell to the Default style
                    cell = new UITableViewCell (UITableViewCellStyle.Default, this._cellIdentifier);

                    // This changes the style of the UITableViewCell to the Subtitle style,
                    //  which displays a second line of text within the cell.
                    // cell = new UITableViewCell (UITableViewCellStyle.Subtitle, this._cellIdentifier);

                    // Instantiate a cell accessory here
                    uiSwitch = new UISwitch (new RectangleF (0f, 0f, 20f, 20f));
                    uiSwitch.Tag = indexPath.Row;
                    uiSwitch.ValueChanged += (object sender, EventArgs e) => {
                        Console.WriteLine ("Cell Switch value is now {0}", uiSwitch.On);
                    };
                    _vRMs.View.AddSubview (uiSwitch);

                    // keep a reference to each cell you create,
                    //  e.g. add them to a static List<UITableViewCell>.
                    //  The GC won't be able to collect them so the event handler will work later.
                    cells.Add (cell);
                }

                //---- create a shortcut to our item
                TableViewItem item = this._TableViewItemGroupList[indexPath.Section].Items[indexPath.Row];

                cell.TextLabel.Text = item.Name;
                cell.Accessory = UITableViewCellAccessory.DisclosureIndicator;
                cell.AccessoryView = uiSwitch;
                // cell.DetailTextLabel.Text = item.SubHeading;

                // Add an image if needed
                /*
                if(!string.IsNullOrEmpty(item.ImageName))
                {
                    cell.ImageView.Image = UIImage.FromFile("Images/" + item.ImageName );
                }
                */

                return cell;
            }
#endregion
        } // end TableViewDataSource Class
#endregion

        #region CLASS TableViewItemGroup
        //========================================================================
        /// <summary>
        /// A group that contains table items
        /// </summary>
        public class TableViewItemGroup {
            public string Name { get; set; }
            public string Footer { get; set; }

            public List<TableViewItem> Items {
                get { return this._items; }
                set { this._items = value; }
            }

            protected List<TableViewItem> _items = new List<TableViewItem>();

            public TableViewItemGroup () {
            }
        }
#endregion

        #region CLASS TableViewItem
        //========================================================================
        /// <summary>
        /// Represents our item in the table
        /// </summary>
        public class TableViewItem {
            public string Name { get; set; }
            public string SubHeading { get; set; }
            public string ImageName { get; set; }

            public TableViewItem () {
            }
        }
#endregion

#endregion

        #region OBSOLETE methods
        // ***************************** OBSOLETE
        // ***************************** OBSOLETE
        // ***************************** OBSOLETE
        [Obsolete]
        public override void ViewDidUnload () {
            base.ViewDidUnload ();

            // Clear any references to subviews of the main view in order to
            // allow the Garbage Collector to collect them sooner.
            //
            // e.g. myOutlet.Dispose (); myOutlet = null;

            ReleaseDesignerOutlets ();
        }

        [Obsolete]
        public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation) {
            // Return true for supported orientations
            return (toInterfaceOrientation != UIInterfaceOrientation.PortraitUpsideDown);
        }
#endregion

    }
}`

2 个答案:

答案 0 :(得分:1)

您的代码存在一些问题。


首先,我认为您的代码示例错过了一个重要部分?

UISwitch变量的范围是什么?看起来这是一个班级参考?


其次,我认为您的代码并不能很好地处理单元格重用 - 在重用的情况下不会调用行uiSwitch.Tag = indexPath.Row;


第三,我不太确定你的方法是否真正具有可扩展性 - 尽管它适用于小型列表


老实说,你可能最好只为这个开关创建一个自定义单元格 - 然后使用这些自定义单元格中的值...要创建自定义单元格,请参阅:

答案 1 :(得分:1)

除了Stuart指出的问题之外,另一个问题是你正在回收细胞,所以你可能最终得到一个指向另一个状态的再生细胞,而不是你想要的。

对于这样的情况,您可以为您创建的每个UISlider使用唯一键,以确保您永远不会为两个不同的变量重用UISlider。或者,您需要更改代码,以便处理程序根据对其执行操作的IndexPath来告知不同的代码。