如何交换UIScrollViews?

时间:2012-01-31 20:58:41

标签: objective-c ios uiscrollview

让我们假设我有2个UIScrollViews,里面有不同的UIImageViews。当我触发一个动作时,我希望将第二个UIScrollView的内容,参数等(除了位置)传递到第一个UIScrollView。

所以,这是我提出的代码:

-(void) someAction {
UIScrollView * scroll = [[UIScrollView alloc] init]; // create an intermediary scrollView
scroll = secondScroll; // here I intent to pass the content of secondScroll to scroll
scroll.frame = firstScroll.frame; // here I assign the frame of firstScroll to scroll
so that it doesn't take the frame of secondScroll;
firstScroll =scroll;  // and then pass all the contents of scroll to firstScroll;     
}

但是当我执行该操作并触发操作时,firstScroll似乎采用了secondScroll的内容,但是secondScroll似乎被删除了。我需要它保持原样。

任何帮助?

由于

4 个答案:

答案 0 :(得分:0)

-(void) someAction {
    UIScrollView * scroll = [[UIScrollView alloc] init]; // create an intermediary scrollView

那是错的。你将使用它泄漏内存,因为在将其分配给另一个对象后,你将丢失指向该滚动视图的指针。你最好简单地声明UIScrollView * scroll;为此目的。

    scroll = secondScroll; // here I intent to pass the content of secondScroll to scroll

但事实并非如此。滚动视图不会神奇地复制自己;如果您将一个指定给另一个,则只指定指针。

    scroll.frame = firstScroll.frame; // here I assign the frame of firstScroll to scroll
    // so that it doesn't take the frame of secondScroll;

所以,从现在开始,如果你在scroll上操作,它将影响secondScroll。

    firstScroll = scroll;  // and then pass all the contents of scroll to firstScroll;     

然后,将firstScroll分配给SecondScroll。因此,firstScroll现在基本上是secondScroll,失去它(一次又一次地泄漏内存)并且没有做任何有用的事情。

}

你想用这个做什么?

假设你想要交换两个视图,你应该做这样的事情:

BOOL firstScrollVisible = NO; // in -init or whatever

- (void) someAction
{
    if (fistScrollVisible)
        [self.view bringSubviewToFront:secondScroll];
    else
        [self.view bringSubviewToFront:firstScroll];
    firstScrollVisible = !firstScrollVisible;
}

答案 1 :(得分:0)

尝试执行以下操作:

- (void)someAction {
    [firstScroll removeFromSuperview]; // So that we do not leave the old firstScroll as a subview
    firstScroll = [secondScroll copy]; // Makes a copy of secondScroll and stores it in firstScroll
    [self addSubview:firstScroll]; // Add the new firstScroll to the view
}

重要提示:
此代码泄漏内存,因为-copy会返回引用计数为+1的对象,但我们不会释放firstScroll。我高度建议您将firstScrollsecondScroll转换为nonatomic, retain属性(@property (nonatomic, retain) UIScrollView *firstScroll)。如果您想了解更多信息,请询问。此外,当运行此代码时,您需要确保firstScrollsecondScroll永远不会是垃圾值(它会崩溃) - 取决于调用的时间和方式,您可能没问题。

答案 2 :(得分:0)

@ jrtc27感谢您的回答。我想我找到了一个解决方案,它似乎完成了我正在寻找的东西。但我不确定这是不是正确的方式。这是我的所作所为:

- (void)someAction {
    [[firstScroll subviews] makeObjectsPerformSelector:@selector(removeFromSuperView:);//here I sort of blank out the content of the firstScroll
    NSArray * array = [secondScroll subviews];//place all subview of the secondScroll in array
    int i = 0;
    int nrOfSubviews = [array count];
    for (i=0;i<nrOfSubviews;i++) { //appoint them one by one to firstScroll
        [firstScroll addSubview:[array objectAtIndex:i]];
    }
}

答案 3 :(得分:0)

如果要克隆UI元素,可以使用NSCoder(就像nib文件加载器一样)。

NSData *scrollViewData = [NSKeyedArchiver archivedDataWithRootObject:self.firstScroll];
CGRect oldFrame = self.secondScroll.frame;
self.secondScroll = [NSKeyedUnarchiver unarchiveObjectWithData:scrollViewData];
self.secondScroll.frame = oldFrame;

这会将UIView及其所有子视图序列化为NSData,然后从NSData创建完整副本。