Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: Как динамически изменять высоту TableView при изменяющихся высотах CustomViewCell

Здравствуйте. Пишу на Mono но думаю, что с кодом на Obj-C разберусь. В общем есть UITableView заполняю его кастомными ячейками для каждой из которых считаю высоту вот так:
Кликните здесь для просмотра всего текста
Код C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public override float GetHeightForRow (UITableView tableView, NSIndexPath indexPath)
        {
            try{
            if (TextLabelList.Count != 0) 
            {
                string item = TextLabelList [indexPath.Row];
                var cell = tableView.DequeueReusableCell("CellID") as customViewCell;
                if (cell == null)
                    cell = new customViewCell();
                var Font = cell.text_cell1.Font;
 
                    SizeF size = new SizeF (tableView.Frame.Width/2, float.MaxValue);
                    float height = cell.text_cell1.StringSize(item, Font, size, UILineBreakMode.WordWrap).Height+Font.PointSize; 
                    indexPath.Row));
    
                return height;
 
            } 
                else
                    return 1f;
            }
            catch
            {
                return 1f;
            }
        }

Ячейки отображаются нормально, но вот в TableView все не влазят. Появляется полоса прокрутки. Подскажите как и где переопределять высоту TableView в зависимости от суммы высот СustomViewCell? Заранее спасибо!
Ответ: Да, вы правы. В моем случае дело было в остальной (корявой) разметке вьюхи. Что то ограничевало размер TableView снизу.
Вопрос: Как программно сделать текущей строку в Tableview

Как программно сделать текущей строку в Tableview.
Не могу найти в инете как программно сделать текущей строку в Tableview.
Ответ:
добавил перед tableView self и все заработало, загадка?
Код

                    [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:NO];

Вопрос: Не раскрывается (исчез) TableView на ScrollView

Здравствуйте. Есть TableView, на обычной вьюхе всё работает нормально. Высота ячеек рассчитывается и т.д. Но вот когда я сделал вью контроллер freeform и задал необходимую высоту и ниже трех лейблов положил я ScrollView, а на него уже положил TableView, и еще один View, то TableView перестал раскрываться. Т.е. его вообще не видно! Почему так? Вчера весь день просидел, экспериментировал с разметкой, но впустую. Вариант моей разметки на вложенном скриншоте. Подскажите что не так? Если кто возьмется помочь, могу выслать файл сториборда на мыло. Заранее спасибо!
Ответ: Да стрелочка есть. Пишет: Scrollable content size is ambiguous for "Scroll View". и Height is ambiguous for "Section Table View". Но как это исправить я не знаю!.. Выслал файл на почту. И сюда прикреплю за одно, может кто посмотрит, исправит.
Вопрос: Правильная обработка нажатя кнопки в TableView

Здравствуйте. Пишу на Mono. Заполнил таблицу кастомными ячейками, состоящими из кнопки и лейбла и огбычными. При нажатии на кнопку в ячейке соответствующая ячейка должна удалиться. Вот код:
Кликните здесь для просмотра всего текста

Код C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
        {
            _tableView = tableView;
 
            var cur_lang =  _User_Data.cur_lang;
 
            if (TextLabelList.Count > 0)
                TextLabelList.RemoveRange (0, TextLabelList.Count);
 
            TextLabelList.Add (cur_lang._add_str);
            TextLabelList.Add (cur_lang._del_all);
 
            foreach (string str in _User_Data.name_mash_picker_list)
                TextLabelList.Add (str);
 
 
            //первые две и после основного списка ячейки идут с кнопкой
            if ((indexPath.Row < 2) || (indexPath.Row >= _User_Data.name_mash_picker_list_start_Count+2)) 
            {
                //"CellID_But"
                var cell = tableView.DequeueReusableCell ("CellID_But") as customViewCell_with_Button;
 
                if (cell == null)
                    cell = new customViewCell_with_Button ();
                    
 
                if (cell.cell_button.Tag == 0) {
                    cell.cell_button.Tag = indexPath.Row;
                    cell.cell_button.TouchUpInside += Touch_Delbtn_on_cell;
                }
                            
                cell.cell_Label.Text = TextLabelList [indexPath.Row];
 
                return cell;
            } 
            else
            {
                //далее обычные ячейки
                UITableViewCell cell = tableView.DequeueReusableCell ("cellIdentifier");
                // if there are no cells to reuse, create a new one
                if (cell == null)
                    cell = new UITableViewCell (UITableViewCellStyle.Default, "cellIdentifier");
                cell.TextLabel.Text = TextLabelList [indexPath.Row];;
                return cell;
            }
 
 
        }
 
 
               void Touch_Delbtn_on_cell(object sender, EventArgs e) //обработчик нажатия кнопки удалить
        {
            var but = (UIButton)sender;
            _User_Data.name_mash_picker_list.RemoveAt (but.Tag-2); //удалить элемент соответствующий кнопке
 
            _tableView.ReloadData ();
            System.IO.File.Delete (dbPath); //удалить файл
            BinaryWriter bw = new BinaryWriter(new FileStream(dbPath, FileMode.OpenOrCreate));
            for(int i=_User_Data.name_mash_picker_list_start_Count; i<_User_Data.name_mash_picker_list.Count; i++)  //переписать текущий список в файл
                bw.Write(Convert.ToDouble(_User_Data.name_mash_picker_list[i]));
            bw.Close(); 
 
        }

Но так как GetCell вызывается каждый раз при появлении ячейки на экране (например вышла из поля невидимости при скролле), то и обработчик события нажатия добавляется несколько раз и соответственно вызывается потом при нажатии тоже несколько раз. Что приводит к удалению не только своей но и соседних ячеек, так как те уже успели поменять свой индекс в списке. Никакой проверки на то, был ли уже добавлен объекту обработчик событий или нет, я не знаю.. Подскажите как быть в такой ситуации? Подобный вопрос я нашел на ксамариновском форуме, но решения я там что то не увидел: https://forums.xamarin.com/discussio...itableviewcell У меня есть конечно одна идея на этот счёт, но я ещё не проверял, насколько она рабочая. В общем кнопку на ячейке сделать объектом дочернего класса, наследованного от UIButton в котором лишь добавить свойство String_Tag, в которое при добавлении ячейки писалось бы то же самое что и на лейбле. А в обработчике нажатия искать элемент в списке с таким текстом и удалять. Таким образом заходить в обработчик может сколько угодно раз, но удалять только один, в остальных случаях он просто не найдет этот элемент в списке. Но это - костыль, а как правильно? Подскажите.
Ответ:
Метод dequeueReusableCell (начиная с какого-то обновления iOS) сам создает ячейку при необходимости (хотя кажется это работает только если табличка в сториборде, для нибов все по старому).
Я как раз со сторибордом и работаю.
Можно удалить все предыдущие обработчики перед добавлением нового.
Можно, но не известно сколько их было добавлено до этого, чтобы знать сколько удалять.
Можно передавать в кастомную ячейку блок, который будет вызываться при нажатии кнопки (или что там в C# вместо блоков? Лямбды?).
Не до конца понял что вы имеете в виду.
В общем сегодня сделал так, как задумывал на выходные. И все заработало. Переопределил класс кнопки кастомной ячейки дочерним классом от UIButton, добавив в него строковое свойство Tag_String.
И в GetCell написал такой вот код:
Код C#
1
2
3
4
5
6
cell.cell_button.Tag = indexPath.Row;
if(cell.cell_button.Tag_String==null)
        cell.cell_button.TouchUpInside += Touch_Delbtn_on_cell;
cell.cell_button.Tag_String=TextLabelList[indexPath.Row];
cell.cell_button.SetBackgroundImage(image, UIControlState.Normal);
cell.cell_Label.Text = TextLabelList [indexPath.Row];
А в обработчике нажатия вот такой:
Кликните здесь для просмотра всего текста

Код C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    void Touch_Delbtn_on_cell(object sender, EventArgs e)
        {
            var button = (UIMyButton_on_cell)sender;
 
            if (button.Tag == 0) {
                Add_new_element (_tableView);
                return;
            }
            if (button.Tag == 1) {
                Del_all_element (_tableView);
                return;
            }
 
            var findindex = _User_Data.name_mash_picker_list.FindIndex(x => x.Equals(button.Tag_String)); //найти элемент в списке с такой строкой.
            
        
            if(findindex>1)
                _User_Data.name_mash_picker_list.RemoveAt (findindex);//удалить этот элемент
                
            _tableView.ReloadData ();
            System.IO.File.Delete (dbPath); //удалить  файл-список
            BinaryWriter bw = new BinaryWriter(new FileStream(dbPath, FileMode.OpenOrCreate));
            for(int i=_User_Data.name_mash_picker_list_start_Count; i<_User_Data.name_mash_picker_list.Count; i++)  //переписать текущий список в файл
                bw.Write(Convert.ToDouble(_User_Data.name_mash_picker_list[i]));
            bw.Close(); 
 
        }

Теперь в обработчик заходит только один раз и делает все что мне надо. Всем спасибо!
Вопрос: Динамическая высота ячейки

Добрый день. Подскажите как посчитать высоту ячейки? Все приметы которые я нашел в инете, считают высоту ячейки в зависимости от текста в label. У меня же внутри ячейки containerCell находится tableView внутри которого находится n-тое кол=во ячеек с разной высотой. Думал через layout сделать, но не могу понять, что к чему привязывать, в примере с label было понятно что лебл есть всегда просто изменяется его высота, в варианте с ячейками не известно какие там, внутри, будут ячейки и с какой высотой (определяется все это уже при анализе ответа с сервера), или размер containerCell будет меняться в зависимости от размера tableView находящегося внутри или contentView (или как там оно)
Ответ: Я изучаю vk api и решил сделать отображение постов на стенке юзера. Так как в посте могут быть вложения разного типа (аудио, видео, текст, картинка) этим и вызвано вложение в ячейку, которая отвечает за пост, доп. ячеек для каждого типа вложения. А вообще за секции я как то и позабыл, спасибо, что подсказали
Вопрос: Вьюшка под статус баром

Здравствуйте. Пытаюсь отобразить вьюшку под статус баром. При первом отображении все как нужно, но через пол секунды все сдвигается вниз на высоту статус бара + высоту тулбара и на их месте пустота. При следуюших отображениях все сразу внизу. Можно как-то победить это?
Ответ:
Сообщение от Митя800
AutoLayout используете?
да
Сообщение от Митя800
какие действия делаете на момент переворота экрана?
никаких - только портретная ориентация.
Вопрос: Динамические компоненты на Scroll-е (autolayout). Вёрстка

Здравствуйте. В сториборде есть вьюха freeform вышиной примерно 700 на ней во всю растянут scrollview на нем лежит динамически меняющаяся таблица (скролл в ней отключен) и view, который тоже динамически должен менять вышину в зависимости от текста лейбла, лежащего в нем. (См. вложение. лейбл в него на картинке не положен.) Сегодня побывал весь день и так и эдак, но либо таблица не растягивается, либо растягивается не полностью, либо не скроллится либо ещё что нибудь.... У меня идеи иссякли. А очень надо! Помогите пожалуйста. Можно либо архивчик с простеньким проектом к ответу прикрепить, либо так на словах описать что с чем и как связать. Заранее спасибо!
Ответ: Да изложили понятно. И в таблице и так присутствует расчет высоты ячеек, но не в этом, как оказалась суть проблеммы. На одном из форумов , мне подсказали не размещать таблицу и вьюху на скролл, а добавить всё что ниже таблице в её футер. Но тут возникла другая проблемка: Вьюконтроллер притерпел некоторые внешние изменения и теперь выглядит так: см вложение 1. Теперь в футере (выделен бирюзовым) лежит сверху кнопка, ниже его вьюха с лейблами (выделена синим), которая то и расширяется динамически, ниже ещё две кнопки и 3 лейбла. Так вот когда синяя вьюха расширяется, она толкает все низ лежащие компоненты вниз, а самый нижний лейбл, в свою очередь не толкает и не расширяет футер. Т.о. в зависимости от вышины синей вьюхи часть низ лежащих компонентов исчезают, хоть и привязаны к низу футеру жесткими связями. Наверное прийдется сумировать высоту всех компонентов, лежащих в футере и назначать её ему. Но вот не могу понять, почему свойство высоты (Frame.Height) у синей вьюхи меняется только после того, как мы вернулись на этот вьюконтроллер из другого, т.е. только во ViewWillAppear. Хотя по факту, визуально высота его меняется мгновенно, после того, как по нажатию кнопки в лейблы попал соответствующий текст.
Вопрос: Клик по кастом-строке таблицы - переход

привет всем
начал изучать разработку под ios на swift
в общем всё плохо

я легко могу сделать вызов нового окошка (activity) под android, но не могу толком программно вызвать отображение нового окошка чтобы была в открывшемся кнопочка < Back
при клике на определенную строку таблицы я отображаю первый или второй контроллер
при этом до лампочки есть ли хоть какая-то связь между текущим контроллером и FirstViewController. оно работает, но нет кнопки назад.
а вот если назначить segue action show внутри FirstViewController на кнопку чтобы отобразило еще новый контроллер, то всё нормально

в общем заморочка только с программным открытием segue, чтобы была связь с предыдущим конроллером

Код

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        switch indexPath.row {
        case 0:
            let vc = self.storyboard!.instantiateViewControllerWithIdentifier("FirstViewController");
            self.presentViewController(vc, animated: true, completion: nil);
            break;
        case 1:
            let vc = self.storyboard!.instantiateViewControllerWithIdentifier("SecondViewController")    ;
            self.presentViewController(vc, animated: true, completion: nil);
        default:
            break;
        }
    }


как выглядит сторибоард см. вложенный файл

может я не ту функцию вызываю? или где-то не связываю вызванный контроллер с родителем?

Присоединённый файл ( Кол-во скачиваний: 0 )
 
Ответ:
всё. сам решил
нужно было завернуть первый экран в navigation controller
и код переделать так:
Код

let toShow = self.storyboard?.instantiateViewControllerWithIdentifier("SecondViewController");
self.navigationController?.pushViewController(toShow!, animated: false);

Вопрос: Отображение большого количества данных

Здравствуйте. Подскажите как реализовать показ данных из json? Нужно вывести разные данные, картинка, большой текст и короткую информацию. Все данные должны быть редактируемые (ну кроме картинки). Я хочу сделать вывод в tableView, для каждого типа данных создать свой вариант кастомной ячейки (для большого текста textView, для короткой информации textField, для картинки просто картинка большая), но проблема в том как узнать какой это тип данных и какую ячейку использовать? Я не могу придумать по какому признаку делать проверку? Или может быть у кого то есть способ вывода данных по лучше. Загвоздка в том что короткой информации много и эти ячейки нужно создавать программно.

Добавлено через 8 часов 13 минут
Для примера, есть дикшинари с характеристиками машины. В detail отображается картинка машины и ее характеристики цвет, пробег, марка, модель, год выпуска и тд. Вот когда этих характеристик не много, то можно воспользоваться статическими ячейками, но когда таких характеристик много например 20, то в сториборде создавать такие ячейки довольно муторно, особенно если через время нужно чуть-чуть изменить дизайн этих ячеек. Если использовать динамическую таблицу то как программно создавать эти ячейки я не представляю. В ячейке должно быть label и textField. В label будет текст характеристики (напр. "цвет" или "цена"), а в textField значение этой характеристики (белый, красный). И как тогда производить вывод если в каждой ячейке разные данные (в первой цвет, во второй цена). Может есть какие то примеры?
Ответ: Да нет, я пробовал разные способы. И доставать из дикшинари ключи, а потом ключи выводить в label, а Value в textField все отлично если бы не картинка и textView. Потому как если закинуть картинку и textView на view, а значения выводить в табличку, то тогда не срабатывает скролл который бы прокручивал всю вьюшку, а не только tableView. И создать для каждой картинки свой идентификатор, но как узнать когда какой идентификатор нужно использовать?
Вопрос: В одной ячейке таблицы несколько повторяющихся элементов

Добрый день. Прошу помощи в виде совета, а не просьбы написать вместо меня. Учусь работать с VK API и решил вывести посты со стены юзера. Если по одному типу данных в ячейке (одна аудиозапись, одно видео, текст, репост) то все просто и это я реализовал, но потом стал вопрос, что делать если в одном посту будет две фотографии или две и больше аудиозаписи)? Раньше было один пост = одна ячейка таблицы (для каждого типа поста своя кастомная ячейка), но как поступить теперь я даже не могу придумать. Была идея все посты сделать массивами, что бы в массиве постов были массивы с находящимися элементами (где два элемента в массиве где 5), но ничего не получается, так как в один массив добавляются данные из других постов (по типам они одинаковые, но должны быть в разных ячейках). Такого элемента как идентификатор поста я не нашел (что бы сравнивать если эта фотка принадлежит этому посту то добавляем к массиву, если нет то создаем новый. Именно в этом месте я и застрял даже идей уже нет.

Даже если я распределю данные по массивам, как их потом правильно отображать, если с картинками все просто, внутрь ячейки вкинуть колекшнВью и в Колекшине отображать картинки, то как с аудиозаписями поступить? Засунуть внутрь ячейки еще один tableView и уже во внутреннем TV отображать аудиозаписи (вариант хорош тем, что у меня сохранится контроль над кнопкой запуска/остановки файла), но а вообще как этот вариант?
Буду благодарен за помощь в первую очередь интересует то как эти данные сохранить (может в классах или родительском классе создать какое то свойство или массив)
Ответ:
Сообщение от Slava-hacker32
Такого элемента как идентификатор поста я не нашел
вот честно незнаком с вк апи, но может быть они банально по таймстемпу разделяются?
не уверен что за одну секунду реально создать несколько постов, а если и реально, то возможно время уточняется по миллисекундам?

поискал - вот есть , как по мне все доступно описано, как решить ваш первый вопрос,
айдишники есть, все гут

Сообщение от Slava-hacker32
если с картинками все просто, внутрь ячейки вкинуть колекшнВью и в Колекшине отображать картинки, то как с аудиозаписями поступить? Засунуть внутрь ячейки еще один tableView и уже во внутреннем TV отображать аудиозаписи (вариант хорош тем, что у меня сохранится контроль над кнопкой запуска/остановки файла), но а вообще как этот вариант?
второе - а чем колекшн вью "проще" или лучше чем тейбл вью?
как по мне - одно и тоже
раз считаете, что колекшн вью - ок, тогда таблица - тоже ок
другой вопрос - кто будет датасорсом для этих таблиц или колекшнов внутри ячеек
так тут я бы конечно выделил отдельные классы для этого и сделал бы их переменными внутри основного датасорса или контроллера, чтобы они могли тригерить ему свои ивенты, за которые они не могут принять решения сами,
но ради всего святого, не делайте ячейку датасорсом, ячейка - это просто вью