gpt4 book ai didi

ios - 是否可以将 View 放置在彼此之上

转载 作者:技术小花猫 更新时间:2023-10-29 11:11:20 24 4
gpt4 key购买 nike

我正在构建一个 Watch 应用程序,我想在其中将 WKInterfaceImage 与一组 WKInterfaceLabel 对象叠加。似乎无法在 StoryBoard 编辑器中执行此操作。

有没有人能够为 Watch App 实现 View 的布局?

附言。我知道 WKInterfaceGroup setBackgroundImage 方法。因为我想在 WKInterfaceImage 中做一些动画,所以 setBackgroundImage 不会对我不利

最佳答案

您不能将 WKInterfaceObjects 布局在彼此之上。您可以在图像上渲染标签,然后进行设置。您将必须为动画的每一帧渲染标签。我在我的 watch 应用程序中为按钮执行此操作。我生成一个图像,它是我的 UI 的一大块,然后我生成动画的每一帧并为每一帧覆盖按钮文本。然后切割每一帧的图像,这样我就可以在每个按钮上制作动画。当您使用该应用程序时,它看起来像是按钮下方的图像动画,而实际上它是 4 个不同按钮中的 4 个不同动画。

编辑

我想我会添加更多细节。这是我的应用程序的屏幕截图。我猜您想做类似的事情。

enter image description here

enter image description here

首先,在我的 Storyboard中,您需要确保您的组的间距为零。

enter image description here

为了创建这个 UI,我使用了这个辅助类。我已经编辑了这个类(class),只关注需要的部分。

typedef struct
{
CGRect top;
CGRect left;
CGRect right;
CGRect bottom;
} ButtonRects;

@interface GPWatchMapImage ()

@property (readwrite, nonatomic) UIImage* topImage;
@property (readwrite, nonatomic) UIImage* bottomImage;
@property (readwrite, nonatomic) UIImage* leftImage;
@property (readwrite, nonatomic) UIImage* rightImage;

@property (readwrite, nonatomic) CGRect topRect;
@property (readwrite, nonatomic) CGRect bottomRect;
@property (readwrite, nonatomic) CGRect leftRect;
@property (readwrite, nonatomic) CGRect rightRect;


@property (readwrite, nonatomic) UIImage* fullImageWithoutArrows;

@property BOOL addedArrows;


@end

@implementation GPWatchMapImage

-(instancetype)init
{
self = [super init];
if (self)
{

}
return self;
}



-(UIImage*)leftImage
{
if (_leftImage == nil)
{
[self breakUpForButtons];
}
return _leftImage;
}

-(UIImage*)rightImage
{
if (_rightImage == nil)
{
[self breakUpForButtons];
}
return _rightImage;
}

-(UIImage*)topImage
{
if (_topImage == nil)
{
[self breakUpForButtons];
}
return _topImage;
}

-(UIImage*)bottomImage
{
if (_bottomImage == nil)
{
[self breakUpForButtons];
}
return _bottomImage;
}

-(UIImage*)fullImageWithoutArrows
{
[self fullImage]; //make sure we have the full image
if (_fullImageWithoutArrows != nil)
{
return _fullImageWithoutArrows;
}
return _fullImage;
}

-(UIImage*)fullImage
{
if (_fullImage == nil)
{
//This is the rect to create the image in
CGRect rect = CGRectMake(0, 0, self.watchSize.width, self.watchSize.height);

//This is how I generate map images. You will need to do something else
self.generatedMapInfo = [[GPCustomMapMaker instance] makeCustomMapFromConfig:self.mapConfig];
_fullImage = self.generatedMapInfo.mapImage;

}

if (self.showMapArrows && !self.addedArrows)
{
//Add the arrows
[self addButtonArrowsToFullImage];
}


return _fullImage;
}


-(void)addButtonArrowsToFullImage
{
self.addedArrows = YES;

ButtonRects rects = [self buttonRects];
UIImage* img = self.fullImage;
self.fullImageWithoutArrows = img; //save for animations
UIGraphicsBeginImageContext(img.size);

UIColor* color = [UIColor colorWithRed:.4 green:.4 blue:.4 alpha:.6];

//CGSize arrowSize = CGSizeMake(24, 4);
CGSize arrowSize = CGSizeMake(48, 8);
CGFloat edgeOffset = 26;
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(ctx, 6);
CGContextSetLineJoin(ctx, kCGLineJoinRound);
CGContextSetLineCap(ctx, kCGLineCapRound);
CGContextSetStrokeColorWithColor(ctx, color.CGColor);

[img drawAtPoint:CGPointMake(0, 0)];


//Left arrow
CGPoint leftCenter = CGPointMake(rects.left.origin.x + edgeOffset, rects.left.origin.y + rects.left.size.height/2);
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, leftCenter.x + arrowSize.height, leftCenter.y - arrowSize.width/2);
CGContextAddLineToPoint(ctx, leftCenter.x, leftCenter.y);
CGContextAddLineToPoint(ctx, leftCenter.x + arrowSize.height, leftCenter.y + arrowSize.width/2);
CGContextStrokePath(ctx);

CGPoint rightCenter = CGPointMake(rects.right.origin.x + rects.right.size.width - edgeOffset, rects.right.origin.y + rects.right.size.height/2);
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, rightCenter.x, rightCenter.y - arrowSize.width/2);
CGContextAddLineToPoint(ctx, rightCenter.x + arrowSize.height, rightCenter.y);
CGContextAddLineToPoint(ctx, rightCenter.x, rightCenter.y + arrowSize.width/2);
CGContextStrokePath(ctx);


CGPoint topCenter = CGPointMake(rects.top.origin.x + rects.top.size.width/2, rects.top.origin.y + edgeOffset);
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, topCenter.x - arrowSize.width/2, topCenter.y + arrowSize.height);
CGContextAddLineToPoint(ctx, topCenter.x, topCenter.y);
CGContextAddLineToPoint(ctx, topCenter.x + arrowSize.width/2, topCenter.y + arrowSize.height);
CGContextStrokePath(ctx);

CGPoint bottomCenter = CGPointMake(rects.bottom.origin.x + rects.bottom.size.width/2, rects.bottom.origin.y + rects.bottom.size.height - edgeOffset);
CGContextBeginPath(ctx);
CGContextMoveToPoint(ctx, bottomCenter.x - arrowSize.width/2, bottomCenter.y);
CGContextAddLineToPoint(ctx, bottomCenter.x, bottomCenter.y + arrowSize.height);
CGContextAddLineToPoint(ctx, bottomCenter.x + arrowSize.width/2, bottomCenter.y);
CGContextStrokePath(ctx);


UIImage* imgWithButtons = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
_fullImage = imgWithButtons;
}

-(UIImage*)subImageInRect:(CGRect)rect fromImage:(UIImage*)image
{
UIGraphicsBeginImageContext(rect.size);

[image drawInRect:CGRectMake(-rect.origin.x, -rect.origin.y, image.size.width, image.size.height)];

UIImage* newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}

-(ButtonRects)buttonRects
{
UIImage* img = self.fullImage;
CGSize size = self.watchSize;
CGFloat topHeight = size.height * .25;
CGFloat bottomHeight = size.height * .25;
CGFloat middleHeight = size.height * .5;

CGRect topRect = CGRectMake(0, 0, size.width, topHeight);
CGRect leftRect = CGRectMake(0, topHeight, img.size.width/2.0, middleHeight);
CGRect rightRect = CGRectMake(img.size.width/2.0, topHeight, img.size.width/2.0, middleHeight);
CGRect bottomRect = CGRectMake(0, topHeight + middleHeight, size.width, bottomHeight);

ButtonRects rects;
rects.top = topRect;
rects.bottom = bottomRect;
rects.left = leftRect;
rects.right = rightRect;

return rects;
}

-(void)breakUpForButtons
{
UIImage* img = self.fullImage;
ButtonRects rects = [self buttonRects];

_topImage = [self subImageInRect:rects.top fromImage:img];
_leftImage = [self subImageInRect:rects.left fromImage:img];
_rightImage = [self subImageInRect:rects.right fromImage:img];
_bottomImage = [self subImageInRect:rects.bottom fromImage:img];
}

@end

接下来在我的 WKInterfaceController 类中,我这样做是为了制作动画。

typedef NS_ENUM(NSInteger, GPWatchImageAnimation)
{
GPWatchImageAnimationNone,
GPWatchImageAnimationSlideLeftToRight,
GPWatchImageAnimationSlideRighToLeft,
GPWatchImageAnimationSlideTopToBottom,
GPWatchImageAnimationSlideBottomToTop,
GPWatchImageAnimationZoomIn,
GPWatchImageAnimationZoomOut
};

#define kNumImagesInMapAnimations 6
#define kMapAnimatinonDuration 0.4

...

-(void)updateMapImageWithAnimation:(GPWatchImageAnimation)animation
{
GPWatchMapImage* previousImage = self.currentMapImage;

//This gets the size of the full image that you want
CGSize size = [self mapSize];
self.currentMapImage = [[GPWatchMapImage alloc] init];
self.currentMapImage.watchSize = size;

//Check if we have a previous image to animate from
if (previousImage != nil && animation != GPWatchImageAnimationNone)
{
NSDictionary* animatedImage = [self animateFromImage:previousImage toImage:self.currentMapImage withAnimation:animation];
[self.mapTopImage setImage:[animatedImage objectForKey:@"top"]];
[self.mapLeftImage setImage:[animatedImage objectForKey:@"left"]];
[self.mapRightImage setImage:[animatedImage objectForKey:@"right"]];
[self.mapBottomImage setImage:[animatedImage objectForKey:@"bottom"]];

[self.mapTopImage startAnimatingWithImagesInRange:NSMakeRange(0, kNumImagesInMapAnimations) duration:kMapAnimatinonDuration repeatCount:1];
[self.mapLeftImage startAnimatingWithImagesInRange:NSMakeRange(0, kNumImagesInMapAnimations) duration:kMapAnimatinonDuration repeatCount:1];
[self.mapRightImage startAnimatingWithImagesInRange:NSMakeRange(0, kNumImagesInMapAnimations) duration:kMapAnimatinonDuration repeatCount:1];
[self.mapBottomImage startAnimatingWithImagesInRange:NSMakeRange(0, kNumImagesInMapAnimations) duration:kMapAnimatinonDuration repeatCount:1];
}
else
{
[self.mapTopImage setImage:self.currentMapImage.topImage];
[self.mapLeftImage setImage:self.currentMapImage.leftImage];
[self.mapRightImage setImage:self.currentMapImage.rightImage];
[self.mapBottomImage setImage:self.currentMapImage.bottomImage];
}

}

-(NSDictionary*)animateFromImage:(GPWatchMapImage*)fromImage toImage:(GPWatchMapImage*)toImage withAnimation:(GPWatchImageAnimation)animation
{
NSMutableArray* topAnimatedImages = [[NSMutableArray alloc] initWithCapacity:kNumImagesInMapAnimations];
NSMutableArray* bottomAnimatedImages = [[NSMutableArray alloc] initWithCapacity:kNumImagesInMapAnimations];
NSMutableArray* leftAnimatedImages = [[NSMutableArray alloc] initWithCapacity:kNumImagesInMapAnimations];
NSMutableArray* rightAnimatedImages = [[NSMutableArray alloc] initWithCapacity:kNumImagesInMapAnimations];

CGSize size = fromImage.fullImage.size;
for (int step = 0; step < kNumImagesInMapAnimations; step++)
{
UIGraphicsBeginImageContext(size);

//render this step
if (animation == GPWatchImageAnimationSlideLeftToRight)
{
CGFloat stepSize = (size.width/2)/kNumImagesInMapAnimations;
CGPoint fromPoint = CGPointMake(-(step+1)*stepSize, 0);
CGPoint toPoint = CGPointMake(size.width/2 - (step+1)*stepSize, 0);
[fromImage.fullImageWithoutArrows drawAtPoint:fromPoint];
[toImage.fullImageWithoutArrows drawAtPoint:toPoint];
}
else if (animation == GPWatchImageAnimationSlideRighToLeft)
{
CGFloat stepSize = (size.width/2)/kNumImagesInMapAnimations;
CGPoint fromPoint = CGPointMake((step+1)*stepSize, 0);
CGPoint toPoint = CGPointMake(-size.width/2 + (step+1)*stepSize, 0);
[fromImage.fullImageWithoutArrows drawAtPoint:fromPoint];
[toImage.fullImageWithoutArrows drawAtPoint:toPoint];
}
else if (animation == GPWatchImageAnimationSlideTopToBottom)
{
CGFloat stepSize = (size.height/2)/kNumImagesInMapAnimations;
CGPoint fromPoint = CGPointMake(0, (step+1)*stepSize);
CGPoint toPoint = CGPointMake(0, -size.height/2 + (step+1)*stepSize);
[fromImage.fullImageWithoutArrows drawAtPoint:fromPoint];
[toImage.fullImageWithoutArrows drawAtPoint:toPoint];
}
else if (animation == GPWatchImageAnimationSlideBottomToTop)
{
CGFloat stepSize = (size.height/2)/kNumImagesInMapAnimations;
CGPoint fromPoint = CGPointMake(0, -(step+1)*stepSize);
CGPoint toPoint = CGPointMake(0, size.height/2 - (step+1)*stepSize);
[fromImage.fullImageWithoutArrows drawAtPoint:fromPoint];
[toImage.fullImageWithoutArrows drawAtPoint:toPoint];
}
else if (animation == GPWatchImageAnimationZoomOut)
{
CGFloat yStepSize = (size.height/2)/kNumImagesInMapAnimations;
CGFloat xStepSize = (size.width/2)/kNumImagesInMapAnimations;
//CGRect fromRect = CGRectMake((step + 1)*xStepSize, (step + 1)*yStepSize, size.width - 2*(step + 1)*xStepSize, size.height - 2*(step + 1)*yStepSize);
CGRect toRect = CGRectMake(-size.width/2 + (step+1)*xStepSize, -size.height/2 + (step+1)*yStepSize, size.width + 2*(kNumImagesInMapAnimations - step - 1)*xStepSize, size.height + 2*(kNumImagesInMapAnimations - step - 1)*yStepSize);
[toImage.fullImageWithoutArrows drawInRect:toRect];

//double alpha = (double)(kNumImagesInMapAnimations - step - 1)/(double)kNumImagesInMapAnimations;
//CGContextSetAlpha(UIGraphicsGetCurrentContext(), alpha);
//[fromImage.fullImageWithoutArrows drawInRect:fromRect];
//CGContextSetAlpha(UIGraphicsGetCurrentContext(), 1.0);
}
else if (animation == GPWatchImageAnimationZoomIn)
{
if (step == kNumImagesInMapAnimations -1)
{
[toImage.fullImageWithoutArrows drawAtPoint:CGPointMake(0, 0)];
}
else
{
CGFloat yStepSize = (size.height/2)/kNumImagesInMapAnimations;
CGFloat xStepSize = (size.width/2)/kNumImagesInMapAnimations;
CGRect fromRect = CGRectMake(-(step + 1)*xStepSize, -(step + 1)*yStepSize, size.width + 2*(step + 1)*xStepSize, size.height + 2*(step + 1)*yStepSize);
//CGRect toRect = CGRectMake(-size.width/2 + (step+1)*xStepSize, -size.height/2 + (step+1)*yStepSize, size.width + 2*(kNumImagesInMapAnimations - step - 1)*xStepSize, size.height + 2*(kNumImagesInMapAnimations - step - 1)*yStepSize);
[fromImage.fullImageWithoutArrows drawInRect:fromRect];
//[toImage.fullImageWithoutArrows drawInRect:fromRect];
}
}
else
{
[toImage.fullImageWithoutArrows drawAtPoint:CGPointMake(0, 0)];
}

UIImage* stepImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();


//Get each of the pieces of the image
GPWatchMapImage* mapImage = [[GPWatchMapImage alloc] init];
mapImage.showMapArrows = self.showMapArrows;
mapImage.fullImage = stepImg;
mapImage.watchSize = [self mapSize];
[topAnimatedImages addObject:mapImage.topImage];
[bottomAnimatedImages addObject:mapImage.bottomImage];
[leftAnimatedImages addObject:mapImage.leftImage];
[rightAnimatedImages addObject:mapImage.rightImage];
}

UIImage* topAnimatedImage = [UIImage animatedImageWithImages:topAnimatedImages duration:kMapAnimatinonDuration];
UIImage* bottomAnimatedImage = [UIImage animatedImageWithImages:bottomAnimatedImages duration:kMapAnimatinonDuration];
UIImage* leftAnimatedImage = [UIImage animatedImageWithImages:leftAnimatedImages duration:kMapAnimatinonDuration];
UIImage* rightAnimatedImage = [UIImage animatedImageWithImages:rightAnimatedImages duration:kMapAnimatinonDuration];
return @{@"top": topAnimatedImage, @"bottom": bottomAnimatedImage, @"left": leftAnimatedImage, @"right": rightAnimatedImage};
}

关于ios - 是否可以将 View 放置在彼此之上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27556113/

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