为MOXY编辑。
我有一组按钮,顶部有一个图像,按钮阵列的视图是背景颜色。当我点击一个按钮我想要检索该按钮索引并使用该索引也获得另一个视图的相应背景颜色..并使用该信息翻转按钮(带图像)和“翻转”到揭示背景色。
我的屏幕组成是,ViewControllersView-> TileView->(按钮数组)。
-(void)viewDidAppear:(BOOL)animated{
_viewContents = [model getRequestedView]; //this retrieves an array of UIButtons(24
//of them) whose frames and background colors have already been initialized to fit
//within the TileView.
_viewFrontImageContents =[model getRequestedViewFrontCardImagesWithFrame:_viewContents];
for(int screenViewIndex = 0; screenViewIndex < [_viewContents count]; screenViewIndex++){
[TileView addSubview:[_viewFrontImageContents objectAtIndex:screenViewIndex]];
[[_viewFrontImageContents objectAtIndex:screenViewIndex] addTarget:self action:@selector(frontOfCardPushed:) forControlEvents:UIControlEventTouchUpInside];
//[TileView addSubview:[_viewContents objectAtIndex:screenViewIndex]];
//[[_viewContents objectAtIndex:screenViewIndex] addTarget:self action:@selector(frontOfCardPushed:) forControlEvents:UIControlEventTouchUpInside];
}
}
// getRequestedViewFrontCardImagesWithFrame方法
-(NSMutableArray *)getRequestedViewFrontCardImagesWithFrame:(NSArray *)views{
NSMutableArray *cards = [[NSMutableArray alloc] init];
UIImage *frontOfCardImage = [UIImage imageNamed:@"Back_of_Tile"];
UIButton *frontOfCardView;
for(int viewIndex = 0; viewIndex < [views count]; viewIndex++){
frontOfCardView = [[UIButton alloc] initWithFrame:[[views objectAtIndex:viewIndex] frame]];
frontOfCardView.backgroundColor = [UIColor colorWithPatternImage:frontOfCardImage];
//setting the tag of each frontCard to match the view index to keep them aligned.
frontOfCardView.tag = viewIndex;
[cards addObject:frontOfCardView];
if(viewIndex == 0){
NSLog(@"first frontcard frame %@, first _viewContentsFrame %@", [cards objectAtIndex:0], [views objectAtIndex:0]);
}
}
return cards;
}
上面我添加的UIButtons顶部有一个图像来代表“扑克牌的正面”。所述按钮的索引完全匹配_viewContents数组的indeces。我设置每个按钮以匹配已经初始化的按钮的框架(大小和位置)。
-(IBAction)frontOfCardPushed:(id)sender{
int containerViewIndex = -1;
UIButton *pressedButton = (UIButton *)sender;
NSLog(@"Button Index: %i", pressedButton.tag);
containerViewIndex = pressedButton.tag;
UIView *container = [TileView viewWithTag:containerViewIndex];
UIView *viewToShow = [_viewContents objectAtIndex:containerViewIndex];
NSLog(@"container: %@, viewToShow: %@", container, viewToShow);
//viewToShow.frame = container.frame;
//NSLog(@"container: %@, viewToShow: %@", container, viewToShow);
[UIView transitionWithView:container duration:0.5 options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
[sender removeFromSuperview];
[container addSubview:viewToShow];
}
completion:nil];
我想要做的是使用转换 - 即“UIViewAnimationTransitionFlipFromRight”来按下“翻转卡片”以显示相关_viewContents数组的内容。我还希望能够让用户翻转卡片以显示frontCardButton的图像。上面的这段代码只关注卡片的第一次翻转以避免代码墙。
我看到了合适的背景颜色 - 但动画本身无效。
我做错了什么,我需要添加/删除这段代码才能使其正常工作?
输出:
//why doesnt the first frontcard frame list a tag? I had just assigned it one?
第一个前卡帧UIButton:0x1c53f020; frame =(6 5; 145 145); opaque = NO; layer = CALayer:0x1c534ac0,首先是_viewContentsFrame UIButton:0x1d045220; frame =(6 5; 145 145); opaque = NO; tag = 3; layer = CALayer:0x1d04535
按钮索引:0
容器:UIView:0x1c53a400; frame =(51 83; 922 614); clipsToBounds = YES; autoresize = W + H; gestureRecognizers = NSArray:0x1d05afe0&gt ;; layer = CALayer:0x1c53a460,viewToShow: UIButton:0x1d045220; frame =(6 5; 145 145); opaque = NO; tag = 3; layer = CALayer:0x1d045350
答案 0 :(得分:3)
更简单的方法是使用[UIView transitionWithView]:
[UIView transitionWithView:self.flipButton
duration:0.8
options:displayingFirstButton ? UIViewAnimationOptionTransitionFlipFromLeft : UIViewAnimationOptionTransitionFlipFromRight
animations:^{
//change image for button
}
completion:^(BOOL finished) {
}];
答案 1 :(得分:2)
您可以使用容器视图来保持按钮。
-(void)viewDidAppear:(BOOL)animated
{
_viewContents = [model getRequestedView]; //this retrieves an array of UIButtons(24 of them) whose frames and background colors have already been initialized to fit within the TileView.
for(int i = 0; i < [_viewContents count]; i++){
UIView *container = [[UIView alloc] initWithFrame:[[_viewContents objectAtIndex:screenViewIndex] frame]];
container.tag = i;
UIButton *frontOfCardView = [[UIButton alloc] initWithFrame:container.bounds];
frontOfCardView.backgroundColor = [UIColor colorWithPatternImage:_frontOfCardImage];
frontOfCardView.tag = i;
[container addSubview:frontOfCardView];
[frontOfCardView addTarget:self action:@selector(frontOfCardPushed:) forControlEvents:UIControlEventTouchUpInside];
[tileView addSubview:container];
}
}
-(IBAction)frontOfCardPushed:(UIButton *)sender
{
UIView *container = [tileView viewWithTag:sender.tag];
UIView *viewToShow = [_viewContents objectAtIndex:index];
viewToShow.frame = sender.frame;
[UIView transitionWithView:container
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
[sender removeFromSuperView];
[container addSubview:viewToShow];
}
completion:nil];
}
我没有测试过,但应该可以使用。无论如何,这不是很干净/漂亮的代码。但是,我知道这只是为了学习目的。
如果它仍然不起作用,请告诉我。
编辑:
我以一个视图控制器为例做了一个简单的项目。我认为你跟踪所有视图/按钮的方式是没用的。在这种情况下,模型只是一种背景颜色,你想要做的只是显示/隐藏它,所以一旦你将颜色分配给按钮,它只需要知道切换状态,所以你甚至不需要(在其他情况下,控制器需要识别接收事件的按钮,以便询问模型所需的内容)
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic, strong) NSArray *colors;
@property (nonatomic, strong) UIView *tileView;
@end
@implementation ViewController
#pragma mark -
#pragma Getters and setters
// I'm assuming the tileView is just a simple view to wrap all the buttons
// PS : propertys should always start with a lowercase letter
-(UIView *)tileView
{
if (!_tileView) {
_tileView = [[UIView alloc] initWithFrame:self.view.bounds];
_tileView.backgroundColor = [UIColor greenColor];
}
return _tileView;
}
// The model: just an array of colors, you can generate it or use other complicated stuff
-(NSArray *)colors
{
if (!_colors) {
_colors = @[[UIColor blackColor], [UIColor redColor], [UIColor grayColor], [UIColor yellowColor],
[UIColor whiteColor], [UIColor blueColor], [UIColor orangeColor], [UIColor darkGrayColor],
[UIColor lightGrayColor], [UIColor cyanColor], [UIColor brownColor], [UIColor magentaColor],
[UIColor blackColor], [UIColor redColor], [UIColor grayColor], [UIColor yellowColor],
[UIColor whiteColor], [UIColor blueColor], [UIColor orangeColor], [UIColor darkGrayColor],
[UIColor lightGrayColor], [UIColor cyanColor], [UIColor brownColor], [UIColor magentaColor]];
}
return _colors;
}
#pragma mark -
#pragma mark Helper methods
#define ROWS 6
#define COLUMNS 4
#define CARD_HEIGHT 60.0f
#define CARD_WIDTH 40.0f
// Gets the width that each card can use based on the chose number of columns
-(CGFloat)horizontalStep
{
return self.tileView.frame.size.width / COLUMNS;
}
// Gets the height that each card can use based on the chose number of columns
-(CGFloat)verticalStep
{
return self.tileView.frame.size.height / ROWS;
}
// Calculates the center for the card frame (return (0,0) if the index is out of bounds)
-(CGPoint)centerForCardAtIndex:(NSUInteger)index
{
CGFloat x = 0.0f, y = 0.0f;
if (index < [self.colors count]) {
x = [self horizontalStep] * 0.5f + (index % COLUMNS) * [self horizontalStep];
y = [self verticalStep] * 0.5f + (index / COLUMNS) * [self verticalStep];
}
return CGPointMake(x, y);
}
// Gets the frame for the card at index
-(CGRect)frameForCardAtIndex:(NSUInteger)index
{
CGPoint center = [self centerForCardAtIndex:index];
CGPoint origin = CGPointMake(center.x - CARD_WIDTH * 0.5f, center.y - CARD_HEIGHT * 0.5f);
return CGRectMake(origin.x, origin.y, CARD_WIDTH, CARD_HEIGHT);
}
-(void)layoutCards
{
// Add tileView to the controller's view
[self.view addSubview:self.tileView];
// Create the card buttons and add them to the tile view
for (int i = 0; i < [self.colors count]; i++) {
UIButton *card = [UIButton buttonWithType:UIButtonTypeCustom];
card.frame = [self frameForCardAtIndex:i];
// The only use of the model IN THIS CASE
card.backgroundColor = self.colors[i];
[card setImage:[UIImage imageNamed:@"back_of_tile.png"]
forState:UIControlStateNormal];
[card addTarget:self
action:@selector(cardPressed:)
forControlEvents:UIControlEventTouchUpInside];
[self.tileView addSubview:card];
}
}
-(void)cardPressed:(UIButton *)card
{
[UIView transitionWithView:card
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromRight
animations:^{
card.selected = !card.selected;
if (!card.selected) {
[card setImage:[UIImage imageNamed:@"back_of_tile.png"]
forState:UIControlStateNormal];
} else {
[card setImage:nil
forState:UIControlStateNormal];
}
}
completion:nil];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self layoutCards];
}