我正在为我的 TableView 创建自定义单元格。我有 8 种不同的细胞。所有细胞都会发生这种情况,但我会为这个例子选择一个来演示发生了什么。我的单元格 NumberCell 中有一个 TextField。您可以在下面看到我如何使用 GetCell 和 SetupDelegates 设置单元格。一切正常,直到我在屏幕上有足够的单元格,您必须开始滚动以创建相同类型的新单元格(这会使旧单元格出队并重新使用)。好吧,我的单元格似乎在交换 answerNumberField.Text,当我将它们从屏幕上滚动然后再打开时,这可能与将 formItem 发送到自定义单元格有关,但我不确定。我想我想知道这是否是在我的自定义单元格中设置我的代表的正确方法。您可以看到我这样做的原因是我可以在单元格中访问 formItem 信息,但这可能是导致问题的原因。我也这样做是为了尝试分离出逻辑,这样我的 GetCell 就不会变得很大。任何帮助将不胜感激,如果您需要更多信息,请询问。谢谢!
注册自定义单元格的 xib 文件:
TableView.RegisterNibForCellReuse (MFNumberCell.Nib, MFNumberCell.Key);
获取单元格
public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{
var cell = new UITableViewCell();
FormItem formItem = formItems [indexPath.Row];
switch (formItem.type) {
case "MFNumber":
var numberCell = (MFNumberCell)tableView.DequeueReusableCell (MFNumberCell.Key, indexPath);
numberCell.SetupDelegates (formItem, detailVC);
cell = numberCell;
break;
...
}
//Remove inset edge constraints
cell.SeparatorInset = UIEdgeInsets.Zero;
cell.LayoutMargins = UIEdgeInsets.Zero;
//Don't show background highlight when selecting the cell
cell.SelectionStyle = UITableViewCellSelectionStyle.None;
return cell;
}
自定义 NumberCell
public void SetupDelegates (FormItem formItem, DetailViewController detailVC)
{
validationView.Layer.MasksToBounds = false;
validationView.Layer.CornerRadius = 13;
//Adds left space before text
answerNumberField.LeftViewMode = UITextFieldViewMode.Always;
if (answerNumberField.LeftView == null) {
UIView leftView = new UIView (new CGRect (0, 0, 15, 25));
answerNumberField.LeftView = leftView;
}
if (!String.IsNullOrWhiteSpace (formItem.answer)) {
answerNumberField.Text = formItem.answer;
} else {
answerNumberField.Text = "";
}
answerNumberField.Placeholder = formItem.placeholder;
answerNumberField.KeyboardType = UIKeyboardType.NumberPad;
questionTextView.Text = formItem.question_text;
UtilHelper.UpdateValidationView(formItem, validationView);
helpButton.TouchUpInside += (object sender, EventArgs e) => {
var okAlertController = UIAlertController.Create ("Help", formItem.help, UIAlertControllerStyle.Alert);
okAlertController.AddAction (UIAlertAction.Create ("OK", UIAlertActionStyle.Default, null));
detailVC.PresentViewController (okAlertController, true, null);
};
answerNumberField.ShouldChangeCharacters += (UITextField tf, NSRange range, string replacementText) => {
string next_answer = tf.Text + replacementText;
bool isMatch = Regex.IsMatch(next_answer, formItem.input_constraint);
if(isMatch){
formItem.answer = next_answer;
}
UtilHelper.UpdateValidationView(formItem, validationView);
return isMatch;
};
answerNumberField.Ended += (object sender, EventArgs e) => {
if (String.IsNullOrWhiteSpace(answerNumberField.Text)) {
formItem.answer = "";
}else{
formItem.answer = answerNumberField.Text;
}
FormGenerator.updateFormItemInSQLiteDatabase (formItem);
UtilHelper.UpdateValidationView(formItem, validationView);
};
}
这是对我有用的解决方案
创建事件处理程序并将它们保存到单元格中,以便您可以在 TableViewSource 的 CellDisplayingEnded 方法中调用 Remove 方法。
public partial class MFNumberCell : UITableViewCell
{
public static readonly UINib Nib = UINib.FromName ("MFNumberCell", NSBundle.MainBundle);
public static readonly NSString Key = new NSString ("MFNumberCell");
public EventHandler helpButtonClick;
public UITextFieldChange answerFieldShouldChangeChar;
public EventHandler answerFieldEnded;
public MFNumberCell (IntPtr handle) : base (handle)
{
}
public static MFNumberCell Create ()
{
return (MFNumberCell)Nib.Instantiate (null, null) [0];
}
public void Update (FormItem formItem, DetailViewController detailVC)
{
validationView.Layer.MasksToBounds = false;
validationView.Layer.CornerRadius = 13;
//Adds left space before text
answerNumberField.LeftViewMode = UITextFieldViewMode.Always;
if (answerNumberField.LeftView == null) {
UIView leftView = new UIView (new CGRect (0, 0, 15, 25));
answerNumberField.LeftView = leftView;
}
if (!String.IsNullOrWhiteSpace (formItem.answer)) {
answerNumberField.Text = formItem.answer;
} else {
answerNumberField.Text = "";
}
answerNumberField.Placeholder = formItem.placeholder;
answerNumberField.KeyboardType = UIKeyboardType.NumberPad;
questionTextView.Text = formItem.question_text;
UtilHelper.UpdateValidationView(formItem, validationView);
// HELP BUTTON START //
helpButtonClick = (s, e) => {
var okAlertController = UIAlertController.Create ("Help", formItem.help, UIAlertControllerStyle.Alert);
okAlertController.AddAction (UIAlertAction.Create ("OK", UIAlertActionStyle.Default, null));
detailVC.PresentViewController (okAlertController, true, null);
};
helpButton.TouchUpInside += helpButtonClick;
// HELP BUTTON END //
// ANSWER TEXT FIELD START //
answerFieldShouldChangeChar = (UITextField tf, NSRange range, string replacementText) => {
string next_answer = tf.Text + replacementText;
bool isMatch = Regex.IsMatch(next_answer, formItem.input_constraint);
if(isMatch){
formItem.answer = next_answer;
}
UtilHelper.UpdateValidationView(formItem, validationView);
return isMatch;
};
answerNumberField.ShouldChangeCharacters += (UITextFieldChange)answerFieldShouldChangeChar;
answerFieldEnded = (s, e) => {
if (String.IsNullOrWhiteSpace (answerNumberField.Text)) {
formItem.answer = "";
} else {
formItem.answer = answerNumberField.Text;
}
FormGenerator.updateFormItemInSQLiteDatabase (formItem);
UtilHelper.UpdateValidationView (formItem, validationView);
};
answerNumberField.Ended += answerFieldEnded;
// ANSWER TEXT FIELD END //
}
public void RemoveDelegates(){
answerNumberField.Ended -= answerFieldEnded;
answerNumberField.ShouldChangeCharacters -= answerFieldShouldChangeChar;
helpButton.TouchUpInside -= helpButtonClick;
}
}
最佳答案
由于每次单元格即将出现时,您都在 GetCell() 中分配委托(delegate),所以每次单元格即将消失时,您也应该在 CellDisplayingEnded() 中删除它们
您应该在 MFNumberCell 中执行一个名为 RemoveDelegates 的方法 并在 CellDisplayingEnded() 上调用它
关于ios - 带有 UITextField : Trouble with Delegates and Dequequing 的自定义 Xib UITableViewCell,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31063597/