¿Es posible colocar vistas una encima de la otra?

Estoy creando una aplicación de Watch donde quiero superponer WKInterfaceImage con un grupo con un montón de objects WKInterfaceLabel. Parece que no puedo hacer esto en el editor StoryBoard.

¿Alguien ha sido capaz de lograr la presentación de puntos de vista uno encima del otro para Watch App?

PD. Estoy al tanto del método setBackgroundImage de WKInterfaceGroup. Como quiero hacer una animation dentro de WKInterfaceImage, setBackgroundImage no me va a depravar

Solutions Collecting From Web of "¿Es posible colocar vistas una encima de la otra?"

No puede diseñar WKInterfaceObjects uno encima del otro. Puede representar las tags sobre su image y luego configurarla. Tendrá que representar las tags para cada fotogtwig de la animation. Lo hago en mi aplicación de reloj para botones. Genero una image que es una gran parte de mi interfaz de usuario, luego genero cada fotogtwig de las animaciones y superpongo el text del button para cada fotogtwig. Luego, corte la image de cada cuadro para que pueda ver las animaciones en cada uno de los botones. Cuando usas la aplicación, parece que la image está animando debajo de los botones, cuando en realidad son 4 animaciones diferentes en 4 botones diferentes.

Editar

Pensé que agregaría algunos más detalles. Aquí hay una captura de pantalla de mi aplicación. Estoy adivinando que quieres hacer algo similar.

introduzca la descripción de la imagen aquí

introduzca la descripción de la imagen aquí

Primero en mi storyboard, debes asegurarte de que el espacio para tus grupos sea cero.

introduzca la descripción de la imagen aquí

Para crear esta interfaz de usuario, uso esta class de ayudante. He editado esta class para enfocarme solo en las partes necesarias.

 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 

A continuación, en mi class WKInterfaceController, hago esto para crear las animaciones.

 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}; } 

En InterfaceBuilder: puede usar un grupo y configurar una image de background de sus activos. Cuando luego agregas una WKInterfaceImage a ese grupo, tienes dos capas para trabajar (si dos capas son suficientes para ti).