以 uiscrollview 的负面方式添加视图并更改 contentsize

Posted

技术标签:

【中文标题】以 uiscrollview 的负面方式添加视图并更改 contentsize【英文标题】:Adding views in the negative way of a uiscrollview and changing contentsize 【发布时间】:2014-05-31 08:16:35 【问题描述】:

我有一个 UIScrollView,其中有一个 calendarView。我现在想要的是下两个月和前两个月已经加载到滚动视图中。

我有以下两种方法。

-(void)addCalendarToEnd
    iPhoneMonthView *phoneCal =  [[iPhoneMonthView alloc] init];
    phoneCal.delegate = self;
    phoneCal.dataSource = self;
    [phoneCal selectDate:[self sameDateByAddingMonths:1 andDate:scrollDate]];
    float xValue = phoneCal.frame.size.width * numberOfCalendarsAfterToday;
    phoneCal.frame = CGRectMake(xValue, 0, phoneCal.frame.size.width, phoneCal.frame.size.height);
    [self.calendarScroll addSubview:phoneCal];
    int numberScroll = numberOfCalendarsBeforeToday + numberOfCalendarsAfterToday + 1;
    calendarScroll.contentSize = CGSizeMake(numberScroll*phoneCal.bounds.size.width,calendarScroll.bounds.size.height);
    [calendarScroll addSubview:phoneCal];
    NSLog(@"CONTENT SIZE IS %f",calendarScroll.contentSize.width);

    numberOfCalendarsAfterToday++;


-(void)addCalenderToBeginning
    iPhoneMonthView *phoneCal =  [[iPhoneMonthView alloc] init];
    phoneCal.delegate = self;
    phoneCal.dataSource = self;
    [phoneCal selectDate:[self sameDateByAddingMonths:-1 andDate:scrollDate]];
    float xValue = phoneCal.frame.size.width * numberOfCalendarsBeforeToday;
    NSLog(@"XVALUE IS %f",xValue);
    phoneCal.frame = CGRectMake(-xValue, 0, phoneCal.frame.size.width, phoneCal.frame.size.height);
    [self.calendarScroll addSubview:phoneCal];
    int numberScroll = numberOfCalendarsBeforeToday + numberOfCalendarsAfterToday + 1;
    calendarScroll.contentSize = CGSizeMake(numberScroll*phoneCal.bounds.size.width,calendarScroll.bounds.size.height);
    NSLog(@"CONTENT SIZE IS %f",calendarScroll.contentSize.width);
    numberOfCalendarsBeforeToday++;

addCalendarToEnd 工作正常。但addCalendarToBeginning 不是。 它在正确的位置添加视图。但我不知道我应该如何设置contentSizeUIScrollView

谁能帮帮我?

编辑

这就是我在 ViewDidLoad 中所做的事情

 scrollDate = [NSDate new];    
    iPhoneMonthView *phoneCal =  [[iPhoneMonthView alloc] init];
    phoneCal.frame = CGRectMake(0, 0, phoneCal.frame.size.width, phoneCal.frame.size.height);
    phoneCal.delegate = self;
    phoneCal.dataSource = self;
    [phoneCal selectDate:[NSDate new]];
    NSLog(@"PHONE CALL HEIGHT IS %f",phoneCal.frame.size.height);
    float xValue = phoneCal.frame.size.width * numberOfCalendarsAfterToday;
    phoneCal.frame = CGRectMake(xValue, 0, phoneCal.frame.size.width, phoneCal.frame.size.height);


    calendarScroll = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, phoneCal.frame.size.width, phoneCal.frame.size.height)];
    calendarScroll.delegate = self;
    [calendarScroll addSubview:phoneCal];
    calendarScroll.backgroundColor = [UIColor clearColor];
    calendarScroll.contentSize =CGSizeMake(numberOfCalendarsAfterToday*phoneCal.frame.size.width,phoneCal.frame.size.height);
    calendarScroll.contentOffset = CGPointZero;

    [self.calendarView addSubview:calendarScroll];
    NSLog(@"PHONE CALL HEIGHT NOW IS %f",phoneCal.frame.size.height);


    numberOfCalendarsBeforeToday++;
    numberOfCalendarsAfterToday++;

【问题讨论】:

为什么要在addCalendarToEnd 中添加两次日历? @mattsven 但你能帮我弄清楚吗?我正在寻找几天的解决方案! 这是你在运行时应该做的事情的顺序。您应该制作 previousMonthView。然后像往常一样将此大小添加到滚动视图的内容大小。然后将滚动视图顶部的所有视图进一步向下移动。然后将 previousMonthView 放在滚动视图的原点(0,0)上。现在您将滚动视图的 contentOffSet 更改为 previousMonthsView 的大小,以便用户觉得您根本没有移动,除了现在他可以向上滚动到前几个月。 @StefGeelen,您需要分页吗?换句话说,需要滚动视图捕捉到完整的页面吗? 【参考方案1】:

如果您只想滚动浏览 5 个月,那么我建议您以线性方式填充内容,然后适当地移动内容偏移量..

因此循环浏览视图,将它们添加到滚动视图并调整框架的原点,使它们彼此齐平。

然后调整contentOffset这样

scrollview.contentOffset.x = 3*phoneCal.frame.size.width;

但是,如果您想滚动查看“无限”量,您应该看看像 DMCircularScrollView 这样的解决方案

【讨论】:

是第二种情况! 试试这个 scrollView.contentOffset = CGPointZero;【参考方案2】:

看起来你让它变得比必要的更难。如果我正确理解您的问题,您应该可以通过执行以下操作来解决您的问题:

-(void)viewDidLoad

   [super viewDidLoad];
    int numberOfMonthViews = 5;
    float monthViewWidth = 320.0f;
    float monthViewHeight = 200.0f;
    self.calendarScroll = [[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, monthViewWidth, monthViewHeight)];
    self.calendarScroll.delegate = self;
    self.calendarScroll.backgroundColor = [UIColor clearColor];

    NSDate* todayDate = [NSDate new];
    int dateOffset = -2;
    for (int i = 0; i < numberOfMonthViews; i++)
    
         iPhoneMonthView *phoneCal =  [[iPhoneMonthView alloc] init];
         phoneCal.delegate = self;
         phoneCal.dataSource = self;
         [phoneCal selectDate:[self sameDateByAddingMonths:dateOffset andDate:todayDate]];
         float xValue = monthViewWidth * i;
         phoneCal.frame = CGRectMake(xValue, 0, monthViewWidth, monthViewHeight);
         [self.calendarScroll addSubview:phoneCal];
         calendarScroll.contentSize = CGSizeMake(xValue + monthViewWidth, monthViewHeight);
         dateOffset++;
    

    self.calendarScroll.contentOffset = CGPoint(monthViewWidth*2, 0.0f);

如果您对我的解决方案有任何疑问,请发表评论。

【讨论】:

【参考方案3】:

对于开始尝试设置您的滚动视图内容偏移量:

calendarScroll.contentOffset = CGPointZero;

【讨论】:

你能给我更多的信息吗?将偏移量设置为 CGPointZero 并不适合我 您能告诉我您在日志中看到的内容吗:其中 x 的值是多少? phoneCal.frame = CGRectMake(-xValue, 0, phoneCal.frame.size.width, phoneCal.frame.size.height); 这是错误的,它把你的视线移出屏幕,把 0 而不是 -320 但这就是重点。那么它将与我在 viewDidload 中添加的视图重叠【参考方案4】:

我不建议您按照您的方式执行此操作 - 事实上,我似乎无法控制数量或重复使用,您将创建无限日历(字面意思)。我建议利用现有的解决方案:

https://github.com/evadne/DayFlow(无限日历)

https://github.com/caesarcat/InfinitePagingView(无限 UIScrollView)

其次,为开始日历的框架设置负值是行不通的,它只会导致它超出可见范围。您必须为其提供 0, 0 的来源,并分流以下所有日历以适应它。

【讨论】:

【参考方案5】:

在您的 addCalendarToEnd 方法中,您将添加 phoneCal 作为 calendarScroll 的子视图,首先使用 self.calendarScroll,最后使用 calendarScroll

而在addCalenderToBeginning方法中,你应该设置contentSize之类的..

calendarScroll.contentSize = CGSizeMake(-(numberScroll*phoneCal.bounds.size.width),calendarScroll.bounds.size.height);

已编辑:

viewDidLoad方法试试

int numberScroll = numberOfCalendarsBeforeToday + numberOfCalendarsAfterToday + 1;
calendarScroll.contentSize = CGSizeMake(numberScroll*phoneCal.bounds.size.width,calendarScroll.bounds.size.height);

并且还在方法addCalenderToBeginning的开头设置numberOfCalendarsBeforeToday++;

如果您有任何不明白的地方,请尝试使用我上面的代码,然后将其作为评论放在此处。

【讨论】:

第一个是错字。但是当我像你说的那样设置内容大小时它不起作用? 我正在制作一个日历应用程序我有一个 CalendarView,其中包含某个月份,例如 6 月在我的 viewDidload 中,我还加载了 6 月前一个月和 6 月后一个月当用户滚动到上个月,前一个月应该添加到滚动视图中 它不工作。但我认为你不明白我想要达到的目标:) 你能解释一下吗 我已经解释了 3 cmets。我想在 UIscrollview 中动态添加 calenderViews 并滚动到 Xvalue 低于 0 的视图。【参考方案6】:

您必须使用contentInset 参数来定义用户的滚动限制。

我猜你只想让它们在顶部日历上达到峰值,除非它们拖动得足够多,此时你将 contentInset.top 设置为负数以“解锁”一个新的滚动区域并让它们进一步向上滚动.

【讨论】:

以上是关于以 uiscrollview 的负面方式添加视图并更改 contentsize的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式将视图添加到情节提要

Swift:以编程方式添加视图时,UIScrollView 的可滚动内容大小不明确,而不使用 IB

无法触摸 UIScrollView 中的 UIButton

以编程方式在 UIScrollView 中居中子视图

以网格模式在 UIScrollView 中添加子视图

将 UIView 从 xib 添加到 UIScrollView