Im still quite new to Xcode and wonder if someone can point out where Im going wrong with some code I took from a tutorial?
The code is to resize a view and it worked in the tutorial. Ive check numerous times and my code is identical to the tutorial and it builds OK.
The code is below. The trouble Im having is that my outlets aren't showing in the connections inspector - so I can't connect to my storyboard.
Many thanks for any assistance.
h file
#import <UIKit/UIKit.h>
#interface MyViewViewController : UIViewController{
CGRect viewMinRect;
IBOutlet UIView *myView;
}
#end
m file
#import "MyViewViewController.h"
#interface MyViewViewController ()
#end
#define MAX_SIZE CGRectMake(100, 100, 100, 100)
#implementation MyViewViewController
- (void)viewDidLoad
{
[super viewDidLoad];
viewMinRect = myView.bounds;
}
- (void)viewDidUnload{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation !=UIInterfaceOrientationPortraitUpsideDown);
}
- (IBAction)animateView:(id)sender{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveLinear];
[UIView setAnimationDuration:0.8f];
if(CGRectEqualToRect(myView.bounds, viewMinRect)){
myView.bounds = MAX_SIZE;
myView.alpha = 1.0;
}
else
{myView.bounds = viewMinRect;
myView.alpha = 0.5;
}
[UIView commitAnimations];
}
#end
Is the class of the view in Interface Builder set to MyViewViewController? If not change it to MyViewViewController.
Related
I have a UILabel that I am animating the constraints for so that it drop down into view. I am using layer.cornerRadius to give the view rounded corners, but for whatever reason after the animation completes the corner radius is removed.
[UIView animateWithDuration:0.3 delay:0 usingSpringWithDamping:0.7 initialSpringVelocity:0.4 options:UIViewAnimationOptionCurveEaseInOut animations:^{
if (shouldShow) {
self.labelOverMapTopConstraint.constant = 16;
} else {
self.labelOverMapTopConstraint.constant = -40;
}
[self.view layoutIfNeeded];
} completion:nil];
cornerRadius is set in viewDidLoad.
Is there a way to prevent this from happening?
I suspect you're subclassing UILabel here since it looks like you have padding in there, is that correct?
There could be something going awry with any custom drawing/calculations you're doing in there, so it would probably be helpful to post that code for inspection as well.
A few questions:
Do you have masksToBounds set to YES?
If you're not using a custom UILabel subclass, are you wrapping the label in a view?
How is the animation being triggered? Is it by a button? A callback from a NSURLRequest? If it's triggered by an async callback are you jumping back on the main queue to perform the animation?
If the animation is triggered automatically within the lifecycle, which lifecycle method is it triggered in?
I wasn't able to reproduce the issue in a test project with a vanilla UILabel. I then tried it with a UILabel subclass which includes additional padding and still wasn't able to reproduce it there.
I've included example code snippets below:
#import "ViewController.h"
#import "R4NInsetLabel.h"
#interface ViewController ()
#property BOOL showingToast;
#property (strong, nullable) IBOutlet R4NInsetLabel *toastLabel;
#property (strong, nullable) IBOutlet NSLayoutConstraint *toastLabelTopConstraint;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationController.navigationBar.titleTextAttributes = #{NSForegroundColorAttributeName : [UIColor whiteColor]};
self.showingToast = NO;
// start with the label pushed off the top of the screen
self.toastLabelTopConstraint.constant = -40.0f;
self.toastLabel.layer.cornerRadius = 6.0f;
self.toastLabel.layer.masksToBounds = YES;
}
- (IBAction)toggleToast:(id)sender {
[UIView animateWithDuration:0.3 delay:0 usingSpringWithDamping:0.7 initialSpringVelocity:0.4 options:UIViewAnimationOptionCurveEaseInOut animations:^{
if (self.showingToast == NO) {
self.toastLabelTopConstraint.constant = 16;
self.showingToast = YES;
} else {
self.toastLabelTopConstraint.constant = -40;
self.showingToast = NO;
}
[self.view layoutIfNeeded];
} completion:nil];
}
#end
#import "R4NInsetLabel.h"
IB_DESIGNABLE
#interface R4NInsetLabel()
#property IBInspectable CGFloat contentPadding;
#property (nonatomic) UIEdgeInsets contentInsets;
- (CGSize)_addInsetsToSize:(CGSize)size;
#end
#implementation R4NInsetLabel
- (UIEdgeInsets)contentInsets {
return UIEdgeInsetsMake(self.contentPadding, self.contentPadding, self.contentPadding, self.contentPadding);
}
- (CGSize)_addInsetsToSize:(CGSize)size {
CGFloat width = size.width + self.contentInsets.left + self.contentInsets.right;
CGFloat height = size.height + self.contentInsets.top + self.contentInsets.bottom;
return CGSizeMake(width, height);
}
- (void)drawTextInRect:(CGRect)rect {
CGRect insetRect = UIEdgeInsetsInsetRect(rect, self.contentInsets);
[super drawTextInRect:insetRect];
}
- (CGSize)intrinsicContentSize {
CGSize baseSize = [super intrinsicContentSize];
return [self _addInsetsToSize:baseSize];
}
- (CGSize)sizeThatFits:(CGSize)size {
CGSize baseSize = [super sizeThatFits:size];
return [self _addInsetsToSize:baseSize];
}
#end
And here's what it looks like:
You also need to set the corner radius on viewDidLayoutSubviews
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
label.layer.cornerRadius = yourValue
}
As the title says, whenever I want to set the text of a UILabel after the animation of the movement of the label, it returns the UILabel back to the origin before the animation. What's interesting is that this only happens when the animation is triggered by a UIButton action.
I've replicated this in a new project. Copy the below code and see what happens.
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (strong, nonatomic) IBOutlet UILabel *hello;
- (IBAction)move:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.hello.text = #"Hello";
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)move:(id)sender {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 1.5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
self.hello.text = #"Howdy";
});
[UIView animateWithDuration:1.0f animations:^{
self.hello.center = CGPointMake(self.hello.center.x + 50, self.hello.center.y + 50);
}];
}
#end
Where self.hello and move are linked to a UILabel and UIButton in the storyboard.
Playing around with this I can see that this error does not occur when instead of using the self.hello.center, you use self.hello.transform = CGAffineTransformMakeTranslation(50, 50). Why is this? Is there any way to continue using .center or do I have to change all of my animations to .transform?
Thanks for your help.
I've had to give into the ways of .transform
Please use constraints rather then modifying centre of label. Such issue happens when we mix auto layout and coordinate system handling. Which I feel you should do something similar to this :
[UIView animateWithDuration:1.0f animations:^{
self.xPos.constant = self.hello.center.x + 50;
self.yPos.constant = self.hello.center.y + 50;
[self.hello layoutIfNeeded];
} completion:^(BOOL finished) {
self.hello.text = #"Howdy";
}];
where xPos and yPos are x and y NSLayoutConstraint position of UILabel
I am a beginner to IOS programming (and programming in general) and I simply don't understand why my code does not shift everything on my screen when the keyboard appears on the screen, as I intend it to. Can someone please help me understand what I am missing here?
ViewController.h
#interface ViewController : UIViewController <UITextFieldDelegate> {
}
#property (strong, nonatomic) IBOutlet UITextField *firstRoommateTextField;
#property (strong, nonatomic) IBOutlet UITextField *secondRoommateTextField;
#property (strong, nonatomic) IBOutlet UILabel *calculatedValueLabel;
- (IBAction)calculateButton:(UIButton *)sender;
- (IBAction)textFieldDismiss2:(id)sender;
- (IBAction)textFieldDismiss1:(id)sender;
#end
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize firstRoommateTextField = _firstRoommateTextField;
#synthesize secondRoommateTextField = _secondRoommateTextField;
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void) animateTextField: (UITextField*) textField up: (BOOL) up
{
const int movementDistance = 210; // tweak as needed
const float movementDuration = 0.3f; // tweak as needed
int movement = (up ? -movementDistance : movementDistance);
[UIView beginAnimations: #"anim" context: nil];
[UIView setAnimationBeginsFromCurrentState: YES];
[UIView setAnimationDuration: movementDuration];
self.view.frame = CGRectOffset(self.view.frame, 0, movement);
[UIView commitAnimations];
}
- (void)textFieldDidBeginEditing:(UITextField *)textField
{
[self animateTextField: textField up: YES];
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
[self animateTextField: textField up: NO];
}
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
I think you forgot to set the delegate for text field which you can set as
_firstRoommateTextField.delegate = self;
_secondRoommateTextField.delegate = self;
in viewDidLoad
or from storyBoard
ctrl+drag from textField to ViewController (right top just below View Controller scene ) and select delegate .
First check the textfield object is assigned to the delegate..i.e.
_firstRoommateTextField.delegate = self;
_secondRoommateTextField.delegate = self;
and then check your delegate methods are getting called or not.
Finally try this, instead of CGRectOffset, try CGRectMake.
i made an UIview as a subview to be as a top slid menu bar when touch button it will slide down and it is work fine but the problem is when it down i can not access any tools or buttons in it
in the .h file
#import <UIKit/UIKit.h>
#interface MainGameVC : UIViewController
{
//IBOutlet UIView *TopMenuViewer;
int Menu;
}
#property (nonatomic, retain) IBOutlet UIView *TopMenuViewer;
#property (strong, nonatomic) IBOutlet UITextField *TestText;
-(IBAction)OpenMenu:(id)sender;
#end
in the .m file
#import "MainGameVC.h"
#interface MainGameVC ()
#property (strong, nonatomic) IBOutlet UITextField *TextBox;
#end
#implementation MainGameVC
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
-(IBAction)OpenMenu:(id)sender{
if (Menu == 0) {
Menu = 1;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:0.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
self.TopMenuViewer.Frame = CGRectMake(0, -100, 0, 0);
[UIView commitAnimations];
[self.view bringSubviewToFront:self.TopMenuViewer];
[self.TopMenuViewer accessibilityElementDidBecomeFocused];
}else{
Menu = 0;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5];
[UIView setAnimationDelay:0.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
self.TopMenuViewer.Frame = CGRectMake(0, 0, 0, 0);
[UIView commitAnimations];
[self.view bringSubviewToFront:self.TopMenuViewer];
[self.TopMenuViewer accessibilityElementDidBecomeFocused];
[self.TopMenuViewer accessibilityElements];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
Menu = 0;
self.TopMenuViewer.Frame = CGRectMake(0, 0, 0, 0);
[
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
/*
#pragma mark - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
#end
Not sure that AllowUserInteraction will solve your issue. This is approach to set options for the animation:
-(IBAction)OpenMenu:(id)sender{
if (Menu == 0) {
Menu = 1;
[UIView animateWithDuration:.5
delay:0.0
options:(UIViewAnimationOptionAllowUserInteraction |
UIViewAnimationOptionCurveEaseInOut)
animations:^
{
self.TopMenuViewer.Frame = CGRectMake(0, -100, 0, 0);
}
completion:^(BOOL finished){
[self.TopMenuViewer accessibilityElementDidBecomeFocused];
}];
Consider attaching the project to the question for us to have a look.
should use UIScrollView instead of UIView
Adding a iAd banner in my app, but when the banner is empty (white) the banner not become hidden, i try two type of code one is:
on my .h
#import <iAd/iAd.h>
#interface HomeViewController : UIViewController <ADBannerViewDelegate> {
ADBannerView *homeBanner;
}
//----------------------------------iAd BANNER-------------------------//
#property (nonatomic, assign) BOOL bannerIsVisible;
#property (nonatomic, strong) IBOutlet ADBannerView *homeBanner;
#end
on class .m
#synthesize homeBanner, bannerIsVisible;
//------------iAd Banner---------------------------------------//
- (void)bannerViewDidload:(ADBannerView *)abanner {
if (!self.bannerIsVisible){
[UIView beginAnimations:#"animationAdBannerOn" context:NULL];
homeBanner.frame = CGRectOffset(homeBanner.frame, 0.0, 50.0);
[UIView commitAnimations];
self.bannerIsVisible = YES;
}
}
- (void)bannerView:(ADBannerView *)aBanner {
if (!self.bannerIsVisible){
[UIView beginAnimations:#"animationAdBannerOff" context:NULL];
homeBanner.frame = CGRectOffset(homeBanner.frame, 0.0, -320.0);
[UIView commitAnimations];
self.bannerIsVisible = NO;
}
}
with this code if the banner is white, continue showing.
Try to a second code:
on my .h
#import <iAd/iAd.h>
#interface HomeViewController : UIViewController <ADBannerViewDelegate> {
ADBannerView *homeBanner;
}
//----------------------------------iAd BANNER-------------------------//
#property (nonatomic, strong) IBOutlet ADBannerView *homeBanner;
#end
and on .m
- (void)viewDidLoad {
[super viewDidLoad];
[homeBanner setHidden:YES];
}
- (void)bannerViewDidload:(ADBannerView *)banner {
[homeBanner setHidden:NO];
NSLog(#"Showing");
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error {
[homeBanner setHidden:YES];
NSLog(#"Hidden");
}
and finally have the same problem.
Any idea?
Thanks.
Did you set the delegate for the bannerView?
Try this in you viewDidLoad -
[homeBanner setDelegate:self];