Это хитрый способ сделать это, но если вы знаете максимальное количество кнопок , которое у вас будет, вы можете добавить его непосредственно в свою ячейку собственного прототипа на раскадровке, не добавляя кнопки программно.
Решение (написано в Swift 4, но общий ответ)
CustomCellTableViewCell.swift
). Он будет содержать все ваши розетки компонентов пользовательского интерфейса. CustomCellTableViewCell.swift
. Теперь файл должен выглядеть примерно так: class CustomCellTableViewCell: UITableViewCell {
@IBOutlet weak var question: UILabel!
@IBOutlet weak var answerOne: UIButton!
@IBOutlet weak var answerTwo: UIButton!
...
...
@IBOutlet weak var answerEight: UIButton!
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
. Не забудьте привести TableviewCell как CustomCell: let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell") as! CustomCellTableViewCell
var answerButtons = [cell.answerButtonOne, cell.answerButtonTwo..., cell.answerButtonEight]
for i in 0..<answerButtons.count {
if i < data[indexPath.row].answers.count { // if the answer exists, add it to the button
cell.answerButton[i].isHidden = false // show button if answer exists
cell.answerButton[i].setTitle(data[indexPath.row], for: .normal)
} else {
cell.answerButton[i].isHidden = true // hide that button
}
}
Ответ фиксированного Jon путем добавления дополнительной анонимной функции:
function create() {
for (var i = 0; i < 5; i++) {
closures[i] = (function(tmp) {
return function() {
alert("i = " + tmp);
};
})(i);
}
}
объяснение состоит в том, что объемами JavaScript является функциональный уровень, не блочный уровень, и создание закрытия просто означает, что объем включения добавляется к лексической среде вложенной функции.
После того, как цикл завершается, переменная функционального уровня i
имеет значение 5
, и это - то, что 'видит' внутренняя функция.
Как примечание стороны: необходимо остерегаться ненужного создания функционального объекта, особенно в циклах; это неэффективно, и если Объекты DOM включены, легко создать циклические ссылки и поэтому представить утечки памяти в Internet Explorer.
Я думаю, что это могло бы быть тем, что Вы хотите:
var closures = [];
function createClosure(i) {
closures[i] = function() {
alert("i = " + i);
};
}
function create() {
for (var i = 0; i < 5; i++) {
createClosure(i);
}
}
Решение состоит в том, чтобы иметь самовыполняющуюся лямбду, обертывающую Ваше нажатие массива. Вы также передаете i как аргумент той лямбде. Значение я в самовыполняющейся лямбде буду тень значение оригинала я, и все будет работать, как предназначено:
function create() {
for (var i = 0; i < 5; i++) (function(i) {
closures[i] = function() {
alert("i = " + i);
};
})(i);
}
Другое решение состояло бы в том, чтобы создать еще одно закрытие, которое получает правильное значение меня и присваивает его другой переменной, которая "поймать" в заключительной лямбде:
function create() {
for (var i = 0; i < 5; i++) (function() {
var x = i;
closures.push(function() {
alert("i = " + x);
});
})();
}
Да закрывают, работают здесь. Каждый раз, когда Вы циклично выполняете функцию, Вы создаете, захватывает i
. Каждая функция, которую Вы создаете, совместно использует тот же i
. Проблема, которую Вы видите, состоит в том, что, так как они все совместно используют тот же i
, они также совместно используют окончательное значение i
, так как это - та же полученная переменная.
Редактирование: Эта статья г-на Skeet объясняет закрытия в некоторой глубине и решает эту проблему в особенности способом, которая намного более информативна тогда, я имею здесь. Однако быть осторожным как способ, которым JavaScript и закрытия дескриптора C# имеют некоторые тонкие различия. Пропуск к разделу, названному "Сравнение стратегий получения: сложность по сравнению с питанием" для его объяснения по этой проблеме.
John Resig Изучение Усовершенствованного JavaScript объясняет это и т.д. Это - интерактивная презентация, которая объясняет много о JavaScript, и примерами является забава читать и выполниться.
Это имеет главу о закрытиях, и этот пример взгляды много как Ваш.
Вот поврежденный пример:
var count = 0;
for ( var i = 0; i < 4; i++ ) {
setTimeout(function(){
assert( i == count++, "Check the value of i." );
}, i * 200);
}
И фиксация:
var count = 0;
for ( var i = 0; i < 4; i++ ) (function(i){
setTimeout(function(){
assert( i == count++, "Check the value of i." );
}, i * 200);
})(i);
Вот то, что необходимо сделать для достижения результата:
<script>
var closures = [];
function create() {
for (var i = 0; i < 5; i++) {
closures[i] = function(number) {
alert("i = " + number);
};
}
}
function run() {
for (var i = 0; i < 5; i++) {
closures[i](i);
}
}
create();
run();
</script>