2013-04-22 2 views
7

Я получаю странное поведение с subviews UIScrollView, идея состоит в том, чтобы создать программно экземпляр UIView с настраиваемым файлом nib, который является формой в моем случае, заполните эту форму данными из класс модели, и добавьте его как subview для моего UIScrollView. Проблема заключается в том, что когда я занимаюсь более чем одним подвью, UIScrollView поддерживает только самое последнее subview, поэтому, если бы я создал три подзаголовка, scrollview покажет только третье (последнее) подвью. Несмотря на то, что элемент управления страницы установлен на число ячеек подложек (три).scrollview показывает только последний добавленный subview

Проект слишком долго, поэтому я попытаюсь объяснить brievely мою проблему с отношение код:

- (void)viewDidLoad { 

    NSArray *sorted = [appArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];//this array contains the data from model, I debugged that to make sure I got the exact data, no more no less :) 


    //Loop all NSManaged objects, for example let's say I have 3 model objects, don't worry about how I get data etc, because I debugged all and maked sure all data objects number are exact, etc. 
    for (App_Table *_appTable in sorted) { 
    //This looped 3 times as expected, I debugged that also and maked sure on each iteration I got the data I expected to have 
    //App_Table is a subclass of NSManagedObject, it's my model class and get its data from coredata file 
    [self addMoreView];//Call this method will create a new subview and add it as subview to the UIScrollView, it will also update the page control, update the content size property, etc. 

    AppTableView *_appTableView = (AppTableView *) [[self.scrollView subviews] lastObject];//Remember addMoreView method create a new instance of AppTableView and add it as subview for the UIScrollView property, then I get that subview to fill it with data here 

    _appTableView.txtADDRESS.text = _appTable.address;//Fill in the form, no need to write all the form fields code because it's the same way. 

    // Scroll To First Page... 
    self.pageControl.currentPage = 0; 
    [self.scrollView scrollRectToVisible:CGRectMake(0, 0, viewWidth, viewHeight) animated:YES]; 

    self.scrollView.contentSize = CGSizeMake(viewWidth*noOfItems, viewHeight);//Set the content size to the sum of subviews width, I also debugged that to check it's correct 
    self.scrollView.delegate = self; 

    [super viewDidLoad]; 
} 

Итак, когда у меня есть три подвидов, то Scrollview загрузит с шириной три подвиды, рассчитанные с помощью данной линии:

self.scrollView.contentSize = CGSizeMake(viewWidth*noOfItems, viewHeight);//Set the content size to the sum of subviews width, I also debugged that to check it's correct 

и я могу прокрутить до 3 ходов (это число подвидов) и UIPageControl также устанавливается в трех точках, но только ONE видна видимость, только последняя, ​​которую я вижу, две другие области обзора исчезли, прокрутка отображает размер содержимого для них, но они не видны. Есть предположения ? Thanx.

EDIT:

Стоит отметить, что в первый раз, когда я изменить вид, все идет хорошо, когда я имею дело с 3-х подвидов, все они видны, но когда я иду к другой точке зрения и получить Вернемся к этому представлению, только последнее подвью видимо.

Кроме того, я работаю над проектом для iPad с разделенным представлением.

EDIT: Это код метода, который начертить новый подвид для UIScrollView

-(IBAction) addMoreView 
    { 

     NSArray *arr = [[NSBundle mainBundle] loadNibNamed:@"AppTableView" owner:self options:nil]; 

     AppTableView *aView = [arr objectAtIndex:0]; 
     [aView setFrame:CGRectMake(startX, 0, aView.bounds.size.width, aView.bounds.size.height)]; 
     [self.scrollView addSubview:aView]; 
     self.scrollView.contentSize = CGSizeMake(self.scrollView.contentSize.width+aView.frame.size.width 
              , self.scrollView.contentSize.height); 


     startX = startX + aView.frame.size.width;//Update the X position, first 0, then 600, 1200, and so on. 
     [self.scrollView scrollRectToVisible:aView.frame animated:YES]; 
     NSLog(@"%f",self.scrollView.contentSize.width); 
     NSLog(@"%f",self.scrollView.contentSize.height); 

    } 

Пусть у меня есть 3 подвидов, метод выше будет называться 3 раза, так как она помещается внутри for петля. Так вот результат NSLogs для приведенного выше метода:

NSLog(@"%f",self.scrollView.contentSize.width); 
NSLog(@"%f",self.scrollView.contentSize.height); 

    First iteration: 

    600.000000 

    0.000000 

    Second iteration: 

    1200.000000 

    0.000000 

    Third iteration: 

    1800.000000 

    0.000000 

EDIT:

Команда предложил ограбить mayoff позволяет мне понять, почему это произошло:

| | | | <AppTableView: 0x1eef4700; frame = (0 18; 600 430); autoresize = LM+RM+TM+BM; tag = 990; layer = <CALayer: 0x1eef4790>> 

    | | | | <AppTableView: 0x1ee3f380; frame = (0 18; 600 430); autoresize = LM+RM+TM+BM; tag = 991; layer = <CALayer: 0x1ee3f410>> 

    | | | | <AppTableView: 0x1ee56910; frame = (0 18; 600 430); autoresize = LM+RM+TM+BM; tag = 992; layer = <CALayer: 0x1ee3f410>> 

Все три subviews рисуются в одном и том же фрейме, поэтому они находятся друг над другом, но когда я отлаживаю это с помощью контрольных точек во время выполнения, x меняется, первый раз 0, затем 600, а затем 1200, что заставляет меня думать, что это d правильно загрузиться. Как исправить это, особенно если значение x будет увеличиваться правильно, так что в чем проблема и почему они все еще используют одну и ту же координату x?

+0

Когда вы говорите, «перейти к другой точке зрения и вернуться к этой точке зрения», как эта точка зрения восстанавливается? Я предполагаю, что это не так; что '-viewDidLoad' вызывается только в первый раз, и проблема находится где-то еще в вашем коде. –

+0

Да, он перестраивается, потому что, когда я выхожу из этого представления, данные сохраняются в модели, а затем, когда я возвращаюсь, данные извлекаются, а подпрограммы перестраиваются. То, что вы имеете в виду '-viewDidLoad, вызывается только до первого раза, я проверил с точками останова, и' viewDidLoad' всегда вызывается при доступе к представлению. – Malloc

+0

Хорошо, тогда, если вы получаете другой результат в разных вызовах '-viewDidLoad', что меняется между двумя вызовами? –

ответ

1

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

Для моего случая scrollview представляет собой пользовательский вид в файле nib. Таким образом, активируя маски Autosizing слева и сверху, ошибка была исправлена.

enter image description here

0

Этот блок кода в -addMoreView проблема:

AppTableView *aView = [arr objectAtIndex:0]; 
[aView setFrame:CGRectMake(startX, 0, aView.bounds.size.width, aView.bounds.size.height)]; 
[self.scrollView addSubview:aView]; 

Если startX никогда не меняется, вы добавляете все эти взгляды на том же месте.

+0

А, это была опечатка, извините, я снова обновил свой пост, на самом деле я использовал статическую переменную, которая повторно инициализируется до 0 при загрузке, затем она увеличивается с увеличением ширины поднабора, чтобы начать рисовать на новой позиции «Х» каждый время. – Malloc

+1

Я предлагаю вам добавить некоторую отладку в '-addMoreView' для печати каждого подвью в вашем прокрутке:' для (UIView * v в self.scrollView.subviews) {NSLog (@ "% @", v);} 'и убедитесь, что что у вас столько просмотров, сколько вы ожидаете, и что их фреймы верны и т. д. –

+0

Привет, Seamus, я уже отлаживал это тоже, а значения по ширине, высоте и Y одинаковы для всех subview, только изменения позиции X от подсмотра до другого. – Malloc

0

Конечно вы не устанавливая размер контента правильно для 3-х элементов:

self.scrollView.contentSize.width+aView.frame.size.width 

должен быть

self.scrollView.contentSize.width+ (aView.frame.size.width * NUMBER_OF_SUBVIEWS) 

Я полагаю, при прокрутке по горизонтали на Scrollview, размер контента позволяет только достаточно места для одно подобие правильное?

+0

Привет, спасибо, я попробовал ваше предложение со скамейки других проб. К сожалению, никто не исправил мою проблему. – Malloc

2

Прежде всего, вы должны поместить вызов [super viewDidLoad] в начало вашего метода - (void)viewDidLoad, а не внизу.

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

0

использовал статическую переменную, которая повторно инициализируется до 0 при нагрузке, а затем увеличивается на ширину поднабора, чтобы начать рисовать новую позицию X.

0

Попробуйте установить autoresizingMask aView на UIViewAutoresizingNone внутри метода addMoreView.

+0

'UIViewAutoresizingNone' является значением по умолчанию для свойства' autoresizingMask'. – Malloc

+0

Из вашего журнала, AutoresizingMask AppTableView является LM + RM + TM + BM. –

0

I created a project, который использует ваш код в сестринском посте, и его работа прекрасна. Я добавил несколько тестов на авторезистирующие маски, как вы можете видеть ниже. Я предлагаю вам сравнить его с тем, что вы делаете. Странные вещи случаются, когда маски на ETIER подвид или scrollView не настроены на привязку к верхнему/левому.

Мой модифицированный код:

NSArray *colors = @[ [UIColor redColor], [UIColor greenColor], [UIColor blueColor] ]; 

UIViewAutoresizing mask; 
mask = [self.scrollView autoresizingMask]; 
//assert(!self.scrollView.autoresizesSubviews); // has no affect here 

if((mask & (UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleBottomMargin)) != mask) NSLog(@"scrollView MASK WRONG"); 

for (int i=0; i<3; ++i) { 

    NSArray *arr = [[NSBundle mainBundle] loadNibNamed:@"AppTableView" owner:self options:nil]; 

    NSLog(@"scrollView frame: %@", NSStringFromCGRect(self.scrollView.frame)); 
    if((mask & (UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleBottomMargin)) != mask) NSLog(@"aView MASK WRONG"); 

    AppTableView *aView = [arr objectAtIndex:0]; 
    assert([aView isKindOfClass:[AppTableView class]]); 
    NSLog(@"orig aView frame: %@", NSStringFromCGRect(aView.frame)); 
    UIViewAutoresizing mask = [aView autoresizingMask]; 
    if((mask & (UIViewAutoresizingFlexibleRightMargin|UIViewAutoresizingFlexibleBottomMargin)) != mask) NSLog(@"aView MASK WRONG"); 


    aView.frame = CGRectMake(startX, 0, aView.bounds.size.width, aView.bounds.size.height); 
    NSLog(@"changed aView frame: %@", NSStringFromCGRect(aView.frame)); 
    aView.backgroundColor = colors[i]; 

    [self.scrollView addSubview:aView]; 
    self.scrollView.contentSize = CGSizeMake(self.scrollView.contentSize.width+aView.frame.size.width 
              ,self.scrollView.contentSize.height); 
    startX = startX + aView.frame.size.width; 

    //AppTableView *_appTableView = (AppTableView *) [[self.scrollView subviews] lastObject]; 

    //_appTableView.txtADDRESS.text = _appTable.address;//Fill in the form, no need to write all the form fields code because it's the same way. 
} 
NSLog(@"scrollView frame: %@", NSStringFromCGRect(self.scrollView.frame)); 
NSLog(@"scrollView contentOffset: %@", NSStringFromCGPoint(self.scrollView.contentOffset)); 
Смежные вопросы