gpt4 book ai didi

ios - UIView animateWithDuration 在 iOS 8 中表现不同

转载 作者:行者123 更新时间:2023-11-28 18:31:49 24 4
gpt4 key购买 nike

我刚从 iOS 7.1 切换到 iOS 8.1。 UIView animateWithDuration 遇到以下问题。图片值一千字,我制作了每个 iOS 下行为的视频:

iOS 7.1:

https://vimeo.com/113887812

iOS 8.1:

https://vimeo.com/113887814

这是一个 iPhone 应用程序。

我应该注意,我在发帖前已经搜索过 SO 和其他地方。这似乎是一个公认的问题,但我发现有一些关于“使用基于约束的动画”(我不明白)和关闭自动布局的引用,但没有真正的共识。

我已经尝试了几次刺伤,但一无所获。如果有人可以指出(或引导我完成)明确的修复,我将不胜感激。

我应该提一下,该应用程序只能在纵向位置工作,所以我在开发过程中没有考虑自动布局。

所有涉及的 View 都是以编程方式创建的,滚动条本身除外。

这是代码。我包括了整个方法,这很长,但我真的不明白新 iOS 中发生了什么变化,所以为了安全起见。 animateWithDuration 调用非常深入到代码块中:


-(void) displayDayChart
{
[self.scroller setBackgroundColor:[UIColor clearColor]];

UIImage *image = [UIImage imageNamed:@"GrayPaper.png"];
self.chartView.backgroundColor = [UIColor colorWithPatternImage:image];

[self.view addSubview:self.scroller];
[self.scroller setScrollEnabled:YES];

[self.scroller setContentSize:CGSizeMake(320, 1800)];
[self.scroller setContentOffset:CGPointMake(0.0, 0.0) animated:YES];

dayBarArray = [[NSMutableArray alloc]init];
infoLabelArray = [[NSMutableArray alloc]init];
timeLabelArray = [[NSMutableArray alloc]init];

timeFrameDC = - 86400; // 24 hours for this test, selectable in real life

[self.scroller.subviews makeObjectsPerformSelector: @selector(removeFromSuperview)];

timeframeDCStart = [NSDate dateWithTimeIntervalSinceNow:timeFrameDC];
timeframeDCEnd = [timeframeDCStart dateByAddingTimeInterval:abs(timeFrameDC)];

actPredicate = [NSPredicate predicateWithFormat:@"(startTime >= %@ AND stopTime <= %@) OR ((startTime <= %@ AND stopTime >= %@) OR (startTime <= %@ AND stopTime == NULL))",timeframeDCStart,timeframeDCEnd,timeframeDCStart,timeframeDCStart,timeframeDCEnd];

NSFetchedResultsController *dayActivityFRC = [TimedActivity MR_fetchAllSortedBy:@"startTime" ascending:YES withPredicate:actPredicate groupBy:nil delegate:nil];


double taDuration;
double activityPercent;
int barHeight;
int lastHeight = 0;
int tickerCount = 1;
int barY;
int lastBarY = 0;
CGRect lastBarFrame;



#pragma mark DisplayDayChart setup

for (TimedActivity *activity in dayActivityFRC.fetchedObjects)
{
// Create bar and associated labels

thisBar = [[DayChartBar alloc] initWithFrame:CGRectZero];

thisInfoLabel = [[UILabel alloc]initWithFrame:CGRectZero];
thisTimeLabel = [[UILabel alloc]initWithFrame:CGRectZero];
arrowView = [[UIView alloc]initWithFrame:CGRectZero];

thisBar.tag = tickerCount;

thisInfoLabel.tag = thisBar.tag + 100;
thisTimeLabel.tag = thisBar.tag + 200;

arrowView.tag = thisBar.tag + 300;
UIImage *image = [UIImage imageNamed:@"LeftArrowRed.png"];


// Add them to the scroller

[self.scroller addSubview:thisBar];
[self.scroller addSubview:thisInfoLabel];
[self.scroller addSubview:thisTimeLabel];
[self.scroller addSubview:arrowView];



NSCalendar *calendar = [NSCalendar currentCalendar];


if (!activity.stopTime) // Currently running
{
if ([activity.startTime timeIntervalSinceDate:timeframeDCStart] < 0)
{
dayBarDurationString = @"24:00:00";
taDuration = (fabs([timeframeDCStart timeIntervalSinceDate:timeframeDCEnd]));
}

else
{
NSDateComponents *components= [calendar components:NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit fromDate:activity.startTime toDate:timeframeDCEnd options:0];
NSInteger hours = [components hour];
NSInteger minutes = [components minute];
NSInteger seconds =[components second];
dayBarDurationString = [NSString stringWithFormat:@"%02li:%02li:%02li",(long)hours,(long)minutes,(long)seconds];

taDuration = (fabs([activity.startTime timeIntervalSinceDate:timeframeDCEnd]));
}
}

else // Either early edge case or fully encapsulated
{
if ([activity.startTime timeIntervalSinceDate:timeframeDCStart] < 0) // Early edge case
{
NSDateComponents *components= [calendar components:NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit fromDate:timeframeDCStart toDate:activity.stopTime options:0];
NSInteger hours = [components hour];
NSInteger minutes = [components minute];
NSInteger seconds =[components second];
dayBarDurationString = [NSString stringWithFormat:@"%02li:%02li:%02li",(long)hours,(long)minutes,(long)seconds];

taDuration = (fabs([activity.stopTime timeIntervalSinceDate:timeframeDCStart]));
}

else if ([activity.startTime timeIntervalSinceDate:timeframeDCStart] > 0) // Encapsulated
{
NSDateComponents *components= [calendar components:NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit fromDate:activity.startTime toDate:activity.stopTime options:0];
NSInteger hours = [components hour];
NSInteger minutes = [components minute];
NSInteger seconds =[components second];
dayBarDurationString = [NSString stringWithFormat:@"%02li:%02li:%02li",(long)hours,(long)minutes,(long)seconds];

taDuration = [activity.duration doubleValue];
}

}


NSDateFormatter *localDateFormatter = [[NSDateFormatter alloc] init];
[localDateFormatter setDateFormat:@"MMM dd"];

NSDateFormatter *localTimeFormatter = [[NSDateFormatter alloc] init];
[localTimeFormatter setDateFormat:@"hh:mm a"];



NSString * timeLabelDateString = [[NSString alloc]init];

NSString * timeLabelTimeString = [[NSString alloc]init];

NSString * timeLabelString = [[NSString alloc]init];


if (([activity.startTime timeIntervalSinceDate:timeframeDCStart] < 0))
{
timeLabelDateString = [localDateFormatter stringFromDate:timeframeDCStart];
timeLabelTimeString = [localTimeFormatter stringFromDate:timeframeDCStart];
}

else
{
timeLabelDateString = [localDateFormatter stringFromDate:activity.startTime];
timeLabelTimeString = [localTimeFormatter stringFromDate:activity.startTime];
}


timeLabelString = [NSString stringWithFormat:@"%@ - %@",timeLabelDateString,timeLabelTimeString];

thisBar.endColor = activity.color;

activityPercent = fabs((taDuration / timeFrameDC) * 100);

if (activityPercent > 100)
{
activityPercent = 100;
}

if (activityPercent < 1.9)
{
activityPercent = 1.9;
}


barHeight = abs((self.scroller.contentSize.height - 100) * (activityPercent / 100));

if (tickerCount == 1)
{
barY = self.scroller.contentSize.height -10;
}

else
{
barY = (lastBarY - lastHeight);
}



#pragma mark DisplayDayChart animation


[UIView animateWithDuration:.8
delay:0.0
options: UIViewAnimationCurveEaseInOut // Deprecated, but still works
animations:^
{
// Starting state *************************************

thisBar.frame = CGRectMake(20, self.scroller.contentSize.height, 130, 0);
thisBar.backgroundColor = [UIColor blackColor];

thisInfoLabel.frame = CGRectMake(20, self.scroller.contentSize.height, thisBar.frame.size.width, 30);

thisTimeLabel.frame = CGRectMake((thisBar.frame.origin.x) + (thisBar.frame.size.width + 35), self.scroller.contentSize.height, 150, 15);

thisTimeLabel.textColor = [UIColor blueColor];

arrowView.frame = CGRectMake(thisTimeLabel.frame.origin.x - 20, thisTimeLabel.frame.origin.y, 16, 16);


thisInfoLabel.textColor = [UIColor clearColor];


// End state *************************************

thisBar.frame = CGRectMake(20, barY, 130, - barHeight);
thisBar.backgroundColor = thisBar.endColor;

thisBar.layer.shadowColor = [[UIColor blackColor] CGColor];
thisBar.layer.frame = CGRectInset(thisBar.layer.frame, 0.0, 3.0);

thisBar.layer.shadowOpacity = 0.7;
thisBar.layer.shadowRadius = 4.0;
thisBar.layer.shadowOffset = CGSizeMake(5.0f, 5.0f);


// Position infoLabel

thisInfoLabel.frame = CGRectMake(20, self.scroller.contentSize.height + ((thisBar.frame.size.height / 2) - 30), thisBar.frame.size.width, 30);


thisTimeLabel.frame = CGRectMake((thisBar.frame.origin.x) + (thisBar.frame.size.width + 35), (thisBar.frame.origin.y) + (thisBar.frame.size.height) - 5, 150, 15);

thisInfoLabel.textColor = [UIColor blackColor];

dayBarNameString = activity.name;

[thisInfoLabel setFont:[UIFont fontWithName:@"Noteworthy-Bold" size:16.0]];

thisInfoLabel.numberOfLines = 0;

thisInfoLabel.textAlignment = NSTextAlignmentCenter;
// thisInfoLabel.layer.borderWidth = 1;


thisInfoLabel.text = [NSString stringWithFormat:@"%@\n%@",dayBarNameString,dayBarDurationString];

[thisInfoLabel sizeToFit];


if ( thisInfoLabel.frame.size.height >= thisBar.frame.size.height)
{
thisInfoLabel.text = [NSString stringWithFormat:@"%@",dayBarNameString];
}

else
{
thisInfoLabel.text = [NSString stringWithFormat:@"%@\n%@",dayBarNameString,dayBarDurationString];
}

[thisInfoLabel sizeToFit];
[thisInfoLabel setHidden:NO];

thisInfoLabel.center = thisBar.center;

arrowView.frame = CGRectMake(thisTimeLabel.frame.origin.x - 20, thisTimeLabel.frame.origin.y, 16, 16);
arrowView.backgroundColor = [UIColor colorWithPatternImage:image];

thisTimeLabel.textColor = [UIColor blueColor];
[thisTimeLabel setFont:[UIFont boldSystemFontOfSize:13]];
thisTimeLabel.numberOfLines = 0;

thisTimeLabel.textAlignment = NSTextAlignmentLeft;

thisTimeLabel.text = timeLabelString;

[thisTimeLabel sizeToFit];


}
completion:^(BOOL finished)
{

[self repositionLabels];

}];


[dayBarArray addObject:thisBar];
[infoLabelArray addObject:thisInfoLabel];
[timeLabelArray addObject:thisTimeLabel];
taDuration = 0;
tickerCount ++;


lastBarY = barY;
lastHeight = barHeight;
lastBarFrame = thisBar.frame;

[self positionInitialDayBarView];

}
}

最佳答案

好的,首先。拒绝使用 Interface Builder,您将失去很多方便的东西。这就像在说“我只使用 Xcode 3,因为它曾经为我工作,所以我就保留了它。”。 Interface Builder 是一款很棒的工具,可以让创建 UI 变得异常简单。

实际问题

你说你没有使用 AutoLayout。这是不正确的。

默认行为(肯定在 iOS8 中,我认为在 iOS7 中)是当你创建一个 UIView(或任何 UI 元素)并将其添加到 View 时,系统将采用 自动调整大小掩码 并应用自动布局约束以匹配调整大小掩码。

这意味着当你做...

UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 100, 21)];
[self.view addSubView:label];

然后标签添加了自动布局约束以将其固定到位置 (10, 10) 和大小 (100, 21)。

然后你不能通过做...来改变框架

label.frame = CGRectMake(10, 50, 100, 21);

因为自动布局约束会把它放回到它开始的地方。

解决方案

有两种解决方案。

正确的解决方案是学习如何使用 AutoLayout。它已经存在 3 年了,并且对 iOS 开发变得越来越重要(即使只是在纵向 iPhone 应用程序上,您现在也有 4 种不同的设备尺寸需要处理)。如果你不开始学习 AutoLayout,你就会落在后面。现在,这几乎是所有 iOS 开发的必要条件。

不正确且非常非常糟糕的解决方案是阻止系统添加这些约束。您可以通过添加行...

label.translatesAutoresizingMaskIntoConstraints = NO;

在创建标签(以及所有其他界面元素)之后。

这将阻止添加这些自动约束并阻止它们干扰您的布局。

虽然这是错误的解决方案。如果您这样做,您只是在推迟必须学习自动布局的时间点。

关于ios - UIView animateWithDuration 在 iOS 8 中表现不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27385681/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com