Ios scrollview仅显示最后添加的子视图

Ios scrollview仅显示最后添加的子视图,ios,objective-c,uiscrollview,Ios,Objective C,Uiscrollview,我在UIScrollView子视图中遇到了奇怪的行为,其想法是使用自定义的nib文件以编程方式创建UIView的一个实例,该文件在我的例子中是一个表单,用模型类中的数据填充该表单,并将其添加为我的UIScrollView的子视图问题是当我处理多个子视图时,UIScrollView只保留最新的子视图,因此如果我创建了三个子视图,scrollview将只显示第三个(最新的)子视图。尽管页面控件设置为Corect子视图数(三个) 项目太长,因此我将尝试用相关的代码简要解释我的问题: - (void)v

我在
UIScrollView
子视图中遇到了奇怪的行为,其想法是使用自定义的nib文件以编程方式创建
UIView
的一个实例,该文件在我的例子中是一个表单,用模型类中的数据填充该表单,并将其添加为我的
UIScrollView
的子视图问题是当我处理多个子视图时,
UIScrollView
只保留最新的子视图,因此如果我创建了三个子视图,scrollview将只显示第三个(最新的)子视图。尽管页面控件设置为Corect子视图数(三个)

项目太长,因此我将尝试用相关的代码简要解释我的问题:

- (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
也设置为三个点,但只有一个子视图可见,只有我能看到的最新一个子视图,其他两个子视图消失,滚动视图计算了它们的内容大小,但它们不可见。有什么想法吗?塔克斯

编辑:

值得注意的是,我第一次编辑视图时,一切正常,当我处理3个子视图时,它们都可见,但是当我转到另一个视图并返回到此视图时,只有最后一个子视图可见

另外,我正在为一个带有拆分视图的iPad项目工作

编辑: 这是为
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
编辑:

rob 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>>
| | | |
|    |    |    | 
|    |    |    | 

所有三个子视图都在同一帧中绘制,因此它们都在彼此的上方,但当我在运行时使用断点调试时,
x
会发生变化,第一次是0,然后是600,然后是1200,这让我认为它绘制正确。如何解决这个问题,特别是x值正确递增,那么问题出在哪里?为什么它们仍然在同一个x坐标上绘制?

-addMoreView
中的这段代码就是问题所在:

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

如果
startX
从未更改,您将在同一位置添加所有这些视图。

您肯定没有正确设置3个项目的内容大小:

self.scrollView.contentSize.width+aView.frame.size.width
应该是

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

我假设当您在scrollview上水平滚动时,内容大小只允许一个子视图有足够的空间,对吗?

首先,您应该将
[super-viewDidLoad]
调用放在
-(void)viewDidLoad
方法的顶部,而不是底部


鉴于您实际看到的内容和期望看到的内容还不够清楚,作为一个可下载的项目提供您的问题的最低工作示例将有助于我们帮助您。如果您只是尝试在不与托管对象交互但使用一些静态提供的数据的单独视图控制器中复制此数据,其他视图控制器将能够自己复制并调试它。或者您也可以自己在这个过程中解决它。

使用了一个静态变量,该变量在加载时重新初始化为0,然后,它会随着子视图的宽度增加,开始在新的X位置上绘图。

尝试在addMoreView方法内将aView的
自动ResizingMask
设置为
UIViewAutoresizingNone

我在姐妹帖子中使用了您的代码,它工作得很好。我在自动调整大小的遮罩上添加了几个测试,如下所示。我建议你把它和你正在做的做比较。当子视图或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));
NSArray*colors=@[[UIColor redColor]、[UIColor greenColor]、[UIColor blueColor];
UIVIEW自动调整掩模;
掩码=[self.scrollView autoresizingMask];
//断言(!self.scrollView.autoresizesSubviews);//在这里没有影响
如果((掩码和(UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin))!=mask)NSLog(@“scrollView掩码错误”);

对于(int i=0;i我回来晚了一点,但最后我找到了解决问题的方法,因此认为分享它以节省其他人的时间是很好的

在我的例子中,scrollview是nib文件中的一个自定义视图。因此,通过激活其左上自动调整大小的遮罩,这个错误得到了修复


当您说“转到另一个视图并返回到此视图”,这个视图正在重建吗?我猜它没有;只有在第一次调用之前才调用
-viewDidLoad
,问题出现在代码中的其他地方。是的,它正在重建,因为当我退出这个视图时,数据存储到模型中,然后当我返回时,检索数据并重建子视图。你的意思是
-viewDidLoad只在第一次调用之前调用
我用断点检查过,在访问视图时总是调用
viewDidLoad。好的,那么如果在对
-viewDidLoad
的不同调用中得到不同的结果,两次调用之间有什么变化?嗨,在每次调用中,我都检查了
contentSize
、数据等。一切都很好,为什么scrollview总是在
for
循环中保留最后一次迭代,虽然它绘制了容纳所有子视图所需的空间,但只显示其中一个?你的
for
循环在哪里结束?你可能需要向我们展示
-addMoreView
的代码。啊,这是一个输入错误,sorry、 我再次更新了我的帖子,实际上我使用了一个静态变量,它在加载时被重新初始化为0,然后