2015-09-02 2 views
0

Я использую UISegmentControl для отображения вопросов объективного типа в виде таблицы. Но, если я выберу один сегмент в любой ячейке, то, если я прокручу, некоторые значения сегмента будут изменены. Я не знаю, как это решить. Прошу вас посоветуйте.Изменение значения UISegment при прокрутке таблицы просмотра

Размер ячейки: 160px

Сегмент оттенок цвета: голубой цвет

Кодирование

//UIViewController 
func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
     return 1 
    } 

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return 10 
    } 

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     let cell = segTblVw.dequeueReusableCellWithIdentifier("segment", forIndexPath: indexPath) as! segmentTblCell 

     return cell 
    } 

//UITableViewCell CLASS 
class segmentTblCell: UITableViewCell { 



    @IBOutlet weak var segMent: UISegmentedControl! 


    override func awakeFromNib() { 
     super.awakeFromNib() 
     // Initialization code 
    } 

    override func setSelected(selected: Bool, animated: Bool) { 
     super.setSelected(selected, animated: animated) 

     // Configure the view for the selected state 
    } 

} 

снимок экрана ниже:

enter image description here

+0

могли бы вы объяснить более, где ваш сегмент? внутри ячейки таблицы? –

+0

есть .. внутри UITableView. Хавин 10 строк. –

+2

Нам нужен код. Однако похоже, что сегментированный элемент управления находится внутри ячейки.В этом случае, когда tableView: cellForRowAtIndexPath вызывается и вы удаляете ячейку, вы должны инициализировать все компоненты внутри ячейки. Поскольку ячейки повторно используются, вы получите несколько компонентов, показывающих значения других ячеек, а не те, которые вы хотите. – ncerezo

ответ

1

Метод 1: Предотвратить повторное использование клеток путем, Держа все объекты ячейки в массиве

var arraysCells : NSMutableArray = []//globally declare this 

в viewDidLoad()

for num in yourQuestionArray//this loop is to create all cells at beginning 
{ 
    var nib:Array = NSBundle.mainBundle().loadNibNamed("SegmentTableViewCell", owner: self, options: nil) 
    var cell = nib[0] as? SegmentTableViewCell 
    arraysCells.addObject(cell!); 
} 

в tableViewDelegate,

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    return arraysCells.objectAtIndex(indexPath.row) as! UITableViewCell 
} 

вы можете найдите выбранные значения сегмента (swer) итерацией arraysCells

Примечание: Метод 1 будет медленным, если у вас есть большое количество клеток

Метод 2: Повторное использование ячейки как обычно, но сохранить состояния (enterd значения) Использование делегата и массивов.

в пользовательских UITableViewCell

@objc protocol SegmentTableViewCellDelegate { 
func controller(controller: SegmentTableViewCell, selectedSegmentIndex:Int, indexPath : NSIndexPath) 
} 

class SegmentTableViewCell: UITableViewCell { 

var delegate: AnyObject? 
var indexPath : NSIndexPath? 

@IBOutlet weak var segment: UISegmentedControl! //outlet of segmented Control 

@IBAction func onSegmentValueChanged(sender: UISegmentedControl/*if the parameter type is AnyObject changed it as UISegmentedControl*/)//action for Segment 
{ 
    self.delegate?.controller(self, selectedSegmentIndex: sender.selectedSegmentIndex, indexPath: indexPath!) 
} 

в ViewController

class MasterViewController: SegmentTableViewCellDelegate{ 
var selectedAnswerIndex : NSMutableArray = [] //globally declare this 
var selectedSegmentsIndexPath : NSMutableArray = [] //globally declare this 


func controller(controller: SegmentTableViewCell, selectedSegmentIndex:Int, indexPath : NSIndexPath) 
{ 
    if(selectedSegmentsIndexPath.containsObject(indexPath)) 
    { 
     selectedAnswerIndex.removeObjectAtIndex(selectedSegmentsIndexPath.indexOfObject(indexPath)) 
     selectedSegmentsIndexPath.removeObject(indexPath) 
    } 
    selectedAnswerIndex.addObject(selectedSegmentIndex) 
    selectedSegmentsIndexPath.addObject(indexPath) 
} 

в cellForRowAtIndexPath (Tableview делегат)

if(selectedSegmentsIndexPath.containsObject(indexPath)) 
{ 
cell?.segment.selectedSegmentIndex = selectedAnswerIndex.objectAtIndex(selectedSegmentsIndexPath.indexOfObject(indexPath)) as! Int 
} 
cell?.delegate = self 
cell?.indexPath = indexPath 

вы можете получить результат на

for index in selectedSegmentsIndexPath 
{ 
    var cellIndexPath = index as! NSIndexPath 
    var answer : Int = selectedAnswerIndex.objectAtIndex(selectedSegmentsIndexPath.indexOfObject(cellIndexPath)) as! Int 
    NSLog("You have enterd answer \(answer) for question number \(cellIndexPath.row)") 
} 
+0

Я думаю, что это не очень хорошая идея, особенно если у вас есть большое количество ячеек –

+0

@ McDonal_11 для метода 1 .. вы получите ответ по индексу 'var: Int = 0 для cell in arraysCells { var cell: SegmentTableViewCell? = arraysCells .objectAtIndex (index) as? SegmentTableViewCell клетки? .segment.selectedSegmentIndex клетки? .switchAnswer.selected NSLog ("ответ на вопрос номер \ (индекс) \ (клетка? .segment.selectedSegmentIndex) или \ (клетка? .switchAnswer.selected)") index ++ } ' –

2

У вас возникла эта проблема из-за того, как работает dequeueReusableCellWithIdentifier:. Каждый раз, когда ячейка прокручивается из экрана, она входит в область кеша, где она будет использоваться повторно.

Предположим, у вас есть 100 ячеек. Все их объекты segmentedControl установлены на first. Вы нажимаете на один, чтобы изменить его значение. Когда ячейка выходит из поля зрения, она входит в кеш, где она будет удалена, если вы прокрутите вниз.

Важно это понимать, потому что объект segmentedControl на самом деле не меняется. Похоже, он меняется из-за поведения dequeue.

Для решения этой проблемы вам необходимо реализовать источник данных, который сохраняет значение объекта segmentedControl, чтобы вы могли его повторно инициализировать каждый раз, когда ячейка была удалена.

+0

Да Спасибо !!! Я понял логику. Можете ли вы объяснить мне кодировку? –

+0

для запуска, установите переменную в области tableViewController, которая содержит значения объекта segmentedControl. Это будет ваш 'dataSource'. Когда вы нажимаете «segmentedControl», убедитесь, что вы обновили значение в переменной. Вы также захотите настроить ячейку на основе переменной dataSource. Вам нужно прочитать на шаблоне MVC –

0

@ KelvinLau совершенна

вы можете сделать это с помощью var segmentedTracker : [NSIndexPath:Int] = [:]

на segmentedValueChanged установить значение SelectedIndex именно: segmentedTracker[indexPath] = valueOf the selected index

затем в чеке cellForRowAtIndexPath для значения let selected = [segmentedTracker]

cell.yourSegmentedControlReference.selectedIndex = selected

обратите внимание, что t его псевдокод, я не помню имя свойства. Отсюда вы можете понять это urself

+0

Я пробовал этот код. Am, сталкиваясь с некоторыми трудностями, чтобы достичь этого. –

0

Я думаю, что использование UISegmentControl в UITableViewCell может быть неправильным.

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UISegmentedControl_Class/

Я никогда не видел такой, что в приложении IOS.

Проблема в том, что UITableViewCell повторно используется методом dequeueReusableCellWithIdentifier. Таким образом, некоторые значения UISegmentControl изменяются при прокрутке.

Хотя это не лучшее решение, вы можете использовать статические ячейки. Что вам нужно сделать, так это то, что переключаются только статические ячейки. И если это так, вы не пишете код UITableViewCell.

enter image description here

0

Год 2018: Обновлен Ответ

Найти мой простой ответ в этом UISegement inside UITableViewCell

=================== ====================================

Год 2015

Я проверил по-своему. Моя кодировка ниже. Пожалуйста, направляйте меня, правильно ли это или неправильно? Моя проблема решена. Этот код останавливает повторное использование ячейки.

Мой Coding Ниже:

//UIViewController 
var globalCell = segmentTblCell() //CUSTOM UITableViewCell Class 

func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
     return 1 
    } 

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return 10 
} 

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cell = segTblVw.dequeueReusableCellWithIdentifier("segment", forIndexPath: indexPath) as! segmentTblCell 

    globalCell = segTblVw.dequeueReusableCellWithIdentifier("segment", forIndexPath: indexPath) as! segmentTblCell //THIS LINE - STOPS REUSABLE TABLE. 

    return cell 
} 
+0

Насколько мне известно, эта линия не остановит многоразовые ячейки –

+0

Спасибо @ShebinKoshy. Я использую это. если я выберу один сегмент в любой ячейке, тогда, если я прокручу, никаких изменений в остальной ячейке ячейки. –

+0

Вы используете панель объявлений? –

Смежные вопросы