我有一个现有的应用程序,其中所有元素的定位都是用代码而不是自动布局编写的。我正在尝试使用现有代码为这些元素添加自动布局。
我试图让这两个按钮并排xButton
显示checkButton
在屏幕底部,这将适用于所有 iPhone 屏幕。当前行为是按钮向屏幕底部偏移。
下面是我的 VFL 所在的代码 - 但是它放置在 UIView 而不是 ViewController 中。
我试图自己解决这个问题,但没有运气,如果有人能帮我解决这个话题以及这个特定问题,我会很高兴的。谢谢
@implementation DraggableViewBackground{
NSInteger cardsLoadedIndex; //%%% the index of the card you have loaded into the loadedCards array last
NSMutableArray *loadedCards; //%%% the array of card loaded (change max_buffer_size to increase or decrease the number of cards this holds)
UIButton* checkButton;
UIButton* xButton;
}
//this makes it so only two cards are loaded at a time to
//avoid performance and memory costs
static const int MAX_BUFFER_SIZE = 2; //%%% max number of cards loaded at any given time, must be greater than 1
static const float CARD_HEIGHT = 386; //%%% height of the draggable card
static const float CARD_WIDTH = 290; //%%% width of the draggable card
@synthesize exampleCardLabels; //%%% all the labels I'm using as example data at the moment
@synthesize allCards;//%%% all the cards
- (void)loadView {
[self setupView];
exampleCardLabels = [[NSArray alloc]initWithObjects:@"Are you in the Technology Industry?",@"Do you have more then 3 years of work experiance?",@"Do you have more then 3 years of work experiance?",@"Are you willing to relocate?",@"Did you enjoy this app?", nil]; //%%% placeholder for card-specific information
loadedCards = [[NSMutableArray alloc] init];
allCards = [[NSMutableArray alloc] init];
cardsLoadedIndex = 0;
[self loadCards];
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[super layoutSubviews];
[self setupView];
exampleCardLabels = [[NSArray alloc]initWithObjects:@"Are you in the Technology Industry?",@"Do you have more then 3 years of work experiance?",@"Do you have more then 3 years of work experiance?",@"Are you willing to relocate?",@"Did you enjoy this app?", nil]; //%%% placeholder for card-specific information
loadedCards = [[NSMutableArray alloc] init];
allCards = [[NSMutableArray alloc] init];
cardsLoadedIndex = 0;
[self loadCards];
}
return self;
}
//%%% sets up the extra buttons on the screen
// VFL Visual Formal Language -
- (void)setupView {
#warning customize all of this. These are just place holders to make it look pretty
self.backgroundColor = [UIColor colorWithRed:.92 green:.93 blue:.95 alpha:1]; //the gray background colors
xButton = [[UIButton alloc]initWithFrame:CGRectMake(60, CGRectGetHeight(self.frame)- 100, 59, 59)];
[xButton setImage:[UIImage imageNamed:@"xButton"] forState:UIControlStateNormal];
[xButton addTarget:self action:@selector(swipeLeft) forControlEvents:UIControlEventTouchUpInside];
[xButton setTranslatesAutoresizingMaskIntoConstraints:NO];
[xButton setBackgroundColor:[UIColor redColor]];
checkButton = [[UIButton alloc]initWithFrame:CGRectMake(200, CGRectGetHeight(self.frame)- 100, 59, 59)];
[checkButton setImage:[UIImage imageNamed:@"checkButton"] forState:UIControlStateNormal];
[checkButton addTarget:self action:@selector(swipeRight) forControlEvents:UIControlEventTouchUpInside];
[checkButton setTranslatesAutoresizingMaskIntoConstraints:NO];
[checkButton setBackgroundColor:[UIColor blueColor]];
[self addSubview:xButton];
[self addSubview:checkButton];
}
#warning include own card customization here!
//%%% creates a card and returns it. This should be customized to fit your needs.
// use "index" to indicate where the information should be pulled. If this doesn't apply to you, feel free
// to get rid of it (eg: if you are building cards from data from the internet)
-(DraggableView *)createDraggableViewWithDataAtIndex:(NSInteger)index
{
DraggableView *draggableView = [[DraggableView alloc]initWithFrame:CGRectMake((self.frame.size.width - CARD_WIDTH)/2,(self.frame.size.height - CARD_HEIGHT)/2, CARD_WIDTH, CARD_HEIGHT)];
draggableView.information.text = [exampleCardLabels objectAtIndex:index];//%%% placeholder for card-specific information
draggableView.delegate = self;
return draggableView;
}
//%%% loads all the cards and puts the first x in the "loaded cards" array
-(void)loadCards
{
if([exampleCardLabels count] > 0) {
NSInteger numLoadedCardsCap =(([exampleCardLabels count] > MAX_BUFFER_SIZE)?MAX_BUFFER_SIZE:[exampleCardLabels count]);
//%%% if the buffer size is greater than the data size, there will be an array error, so this makes sure that doesn't happen
//%%% loops through the exampleCardsLabels array to create a card for each label. This should be customized by removing "exampleCardLabels" with your own array of data
for (int i = 0; i<[exampleCardLabels count]; i++) {
DraggableView* newCard = [self createDraggableViewWithDataAtIndex:i];
[allCards addObject:newCard];
if (i<numLoadedCardsCap) {
//%%% adds a small number of cards to be loaded
[loadedCards addObject:newCard];
}
}
//%%% displays the small number of loaded cards dictated by MAX_BUFFER_SIZE so that not all the cards
// are showing at once and clogging a ton of data
for (int i = 0; i<[loadedCards count]; i++) {
if (i>0) {
[self insertSubview:[loadedCards objectAtIndex:i] belowSubview:[loadedCards objectAtIndex:i-1]];
} else {
[self addSubview:[loadedCards objectAtIndex:i]];
}
cardsLoadedIndex++; //%%% we loaded a card into loaded cards, so we have to increment
}
}
}
#warning include own action here!
//%%% action called when the card goes to the left.
// This should be customized with your own action
-(void)cardSwipedLeft:(UIView *)card;
{
//do whatever you want with the card that was swiped
// DraggableView *c = (DraggableView *)card;
[loadedCards removeObjectAtIndex:0]; //%%% card was swiped, so it's no longer a "loaded card"
if (cardsLoadedIndex < [allCards count]) { //%%% if we haven't reached the end of all cards, put another into the loaded cards
[loadedCards addObject:[allCards objectAtIndex:cardsLoadedIndex]];
cardsLoadedIndex++;//%%% loaded a card, so have to increment count
[self insertSubview:[loadedCards objectAtIndex:(MAX_BUFFER_SIZE-1)] belowSubview:[loadedCards objectAtIndex:(MAX_BUFFER_SIZE-2)]];
}
}
#warning include own action here!
//%%% action called when the card goes to the right.
// This should be customized with your own action
-(void)cardSwipedRight:(UIView *)card
{
//do whatever you want with the card that was swiped
// DraggableView *c = (DraggableView *)card;
[loadedCards removeObjectAtIndex:0]; //%%% card was swiped, so it's no longer a "loaded card"
if (cardsLoadedIndex < [allCards count]) { //%%% if we haven't reached the end of all cards, put another into the loaded cards
[loadedCards addObject:[allCards objectAtIndex:cardsLoadedIndex]];
cardsLoadedIndex++;//%%% loaded a card, so have to increment count
[self insertSubview:[loadedCards objectAtIndex:(MAX_BUFFER_SIZE-1)] belowSubview:[loadedCards objectAtIndex:(MAX_BUFFER_SIZE-2)]];
}
}
//%%% when you hit the right button, this is called and substitutes the swipe
-(void)swipeRight
{
DraggableView *dragView = [loadedCards firstObject];
dragView.overlayView.mode = GGOverlayViewModeRight;
[UIView animateWithDuration:0.2 animations:^{
dragView.overlayView.alpha = 1;
}];
[dragView rightClickAction];
}
//%%% when you hit the left button, this is called and substitutes the swipe
-(void)swipeLeft
{
DraggableView *dragView = [loadedCards firstObject];
dragView.overlayView.mode = GGOverlayViewModeLeft;
[UIView animateWithDuration:0.2 animations:^{
dragView.overlayView.alpha = 1;
}];
[dragView leftClickAction];
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
@end