I'm designing a app where it first shows a terms and conditions view and then on accepting it, it moves on to next view where I've used a UIImage to add a background image, so that I could display a welcome image for my app and then after 5 seconds I have changed the view to user login. I've used the view based application template without storyboards and I've also enabled ARC.
I've used the following codes:
Accepting Terms and Condition [accept.h, accept.m, accept.xib]:
- (IBAction)AcceptPractTandC:(id)sender
{
PractionerImage *PracImage = [[PractionerImage alloc] init];
[self presentViewController:PracImage animated:YES completion:nil];
}
Displaying Image for 5 Seconds and showing next view [PractionerImage.h, PractionerImage.m, PractionerImage.xib]:
- (void)viewDidLoad
{
[super viewDidLoad];
count = 0;
PracImage = [NSTimer scheduledTimerWithTimeInterval:(1.0/1.0) target:self selector:#selector(PracImageSkip) userInfo:nil repeats:YES];
}
- (void)PracImageSkip
{
count += 1;
if (count > 5) {
ViewController *Intro = [[ViewController alloc]init];
[self presentViewController:Intro animated:YES completion:nil];
}
}
and I have the user details in the files ViewController.m, ViewController.h, ViewController.xib.
Related
Maybe this is purely simulator related. I have not tried it on an actual device yet.
I'm on the latest greatest MacBook with a 1TB flash drive, and 95% free processor, and less than full memory consumption.
I have a UIPopoverController with 4 items in it, sized to those items.
There's nothing complicated or multi-threaded or long running in any way associated in the UIPopoverController in question.
I've set the appear and dismiss animation at 0, yet when I tap on an item in the list, there seems to be an random indeterminate delay between 0 and .4 seconds in the popover disappearing. Of course the 0 is expected, but the times when it's nearly a half second is very noticeably longer and disconcerting.
Any idea what may be causing that?
Code that shows the popover...
-(IBAction)theLandImpsButtonPressed:(UIButton *)sender
{
iRpNameValuePopover *thePopoverContent = [[iRpNameValuePopover alloc] init];
thePopoverContent.theTableValues = [self getLandImpsChoicesList];
impsLandPopover = [[UIPopoverController alloc] initWithContentViewController:thePopoverContent];
thePopoverContent.thePopoverController = impsLandPopover;
impsLandPopover.popoverContentSize = [iRpUIHelper sizeForPopoverThatHasTitle:NO andListContent:thePopoverContent.theTableValues];
impsLandPopover.delegate = self;
[impsLandPopover presentPopoverFromRect:self.theLandImpsButton.bounds inView:self.theLandImpsButton permittedArrowDirections:UIPopoverArrowDirectionAny animated:NO];
}
Code that dismisses the popover...
BTW, there is no evaluation time incurred here [self userChoiceIsValid] because it simply returns YES right now.
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
_theChosenNameValueItem = [self.theTableValues objectAtIndex:indexPath.row];
[self acceptUserChoiceAndClose];
}
// This contentViewController is encapsulated INSIDE a UIPopoverViewController, and this class cannot itself
// close the popover which contains it, hence the need for the reference to the popover controller
// It is the popover's delegate... the one that created the popover, that is able to close it.
-(void)acceptUserChoiceAndClose
{
_theUserChoseAValue = NO; // Start by assuming they didn't chose a valid value.
if ([self userChoiceIsValid])
{
// Set variable that indicates the user chose a value which can be saved to core data, and/or presented on screen.
_theUserChoseAValue = YES;
// Close the popover.
[_thePopoverController dismissPopoverAnimated:NO];
// Notify the class that presented the popover that the popover has been dismissed.
// It will still be available to the dismissal method where code can retrieve the user's choice, and set the popover to nil.
if (_thePopoverController.delegate && [_thePopoverController.delegate respondsToSelector:#selector(popoverControllerDidDismissPopover:)])
{
[_thePopoverController.delegate popoverControllerDidDismissPopover:_thePopoverController];
}
}
else
{
[self showValidationFailureMessageToUser];
}
}
Dismissing the viewController in main thread will solve the issue.
dispatch_async(dispatch_get_main_queue(), ^{
[self dismissViewControllerAnimated:YES completion:nil];
});
I would check it out in the profiler and see what the time is being spent on.
There's a good tutorial here.
UIPopoverPresentationController *popOverView;
//////
Dismiss it...
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
[popOverView.presentedViewController dismissViewControllerAnimated:NO completion:nil];
popOverView = nil;
});
});
I am working video player.. I am using MPMediaplayer framework…
In video player below i am displaying one UIView, in this view i am displaying current video details like Video name and video description and video starting time and ending time… Those are details are displayed in UITableview.
The tableview adding to this uiview..Those are all things are done.
The uiview beside i put one button.. if i click the button then automatically appear uiview. if i click again the uiview disappear..this is also done.
now i am integrating animation for uiview like fade out(means if i click button appear uiview, after 10 seconds automatically disappear the uiview… )..that is my main requirement.. This is also done..
But problem is for example user scroll the uiview (video player details in tableview to scroll the tableview up and down) after 10 seconds automatically disappear. if user scroll the video player details i don’t want to disappear my tableview… but my problem if user scroll the video player details it is automatically disappear after 10 seconds..
so plz help me any body..How to handle this thing…My requirement is if user scroll the video player details i don’t want to disappear my tableview…
- (IBAction)InfoVisibleAction:(id)sender
{
if(UIView.hidden==NO)
{
UIView.hidden=YES;
ScheduleImageView.hidden=YES;
tableView.hidden=YES;
timeLabel1.hidden=YES;
}
else
{
UIView.hidden=NO;
ScheduleImageView.hidden=NO;
tableView.hidden=NO;
timeLabel1.hidden=NO;
[self performSelector:#selector(infoHiddenAction:) withObject:nil afterDelay:10];
}
}
- (IBAction)infoHiddenAction:(id)sender
{
if(UIView.hidden==NO)
{
UIView.hidden=YES;
ScheduleImageView.hidden=YES;
tableView.hidden=YES;
timeLabel1.hidden=YES;
}
}
- (IBAction)infoHiddenAction:(id)sender
{
if(UIView.hidden==NO)
{
SupportedView.hidden=YES;
ScheduleImageView.hidden=YES;
tableView.hidden=YES;
timeLabel1.hidden=YES;
}
}
-(void)viewDidLoad
{
tableView=[[UITableView alloc]initWithFrame:CGRectMake(0, 0, 550, 130)];
tableView.delegate=self;
tableView.dataSource=self;
tableView.backgroundColor=[UIColor clearColor];
tableView.scrollEnabled=YES;
tableView.separatorColor=[UIColor clearColor];
[UIView addSubview:tableView];
}
The following should help
In Your class:
#implementation <YourClass> {
NSTimer* hideTimer;
}
Inside (IBAction)InfoVisibleAction:(id)sender
Instead of
[self performSelector:#selector(infoHiddenAction:) withObject:nil afterDelay:10];
Use
[hideTimer invalidate], hideTimer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:#selector(infoHiddenAction:) userInfo:nil repeats:NO];
Implement scrollViewDidScroll
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
[hideTimer invalidate], hideTimer = [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:#selector(infoHiddenAction:) userInfo:nil repeats:NO];
}
Inside (IBAction)infoHiddenAction:(id)sender
Add
[hideTimer invalidate];
In My Application i need to release my NSTimer , when i am moving from one view controller to another view controller . How to release this type of objects in ARC ? i am using below code for creation and releasing NSTimer but Where i have to write this releasing code in view controller?
For Creation.
- (void)viewDidLoad{
[super viewDidLoad];
updateBCK = [NSTimer scheduledTimerWithTimeInterval:(5.0) target:self selector:#selector(changeImage) userInfo:nil repeats:YES];
[updateBCK fire];
}
-(void)changeImage{
static int i=0;
if (i == [myImages count]){
i=0;
}
[UIImageView beginAnimations:nil context:NULL];
[UIImageView setAnimationDuration:0.6];
mainBackgroundImageView.alpha=1;
mainBackgroundImageView.image =[myImages objectAtIndex:i];
NSLog(#"\n The main screen image is %#",[myImages objectAtIndex:i]);
[UIImageView commitAnimations];
i++;
}
For Release.
[updateBCK invalidate];//
updateBCK = nil;
Thanks in Advance.
You should call
[timer invalidate];
timer = nil;
where you push your view controller. If this is an issue, you can still call it in
- (void) viewWillDisappear:(BOOL)animated;
Also, you should initialize it in
- (void) viewDidAppear:(BOOL)animated;
That makes more sense.
When you want to stop time
use below code
[timer invalidate]; // timer is the name of timer object
- (IBAction)button:(id)sender {
SecondViewController *second = [[SecondViewController alloc]
initWithNibName:#"secondViewController"
bundle:nil];
[self presentViewController:second animated:NO completion:nil];
[self.timer invalidate]; // timer is the name of timer object
timer=nil;//it may work without this line too ;not sure
}
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Timers/Articles/usingTimers.html
A timer maintains a strong reference to its target. This means that as long as a timer remains valid, its target will not be deallocated. As a corollary, this means that it does not make sense for a timer’s target to try to invalidate the timer in its dealloc method—the dealloc method will not be invoked as long as the timer is valid.
when i am moving from one view controller to another view controller
Then you should do this in delloc, if you want to do some cleanup tasks when your view is dismissing or released. It's the best place, In such case you can implement it.
-(void)dealloc{
[updateBCK invalidate];//
updateBCK = nil;
}
Hope this helps
When i try to load camera from my code, camera preview is black. If I wait for 10-20 seconds it will show real camera preview. I found several questions and some of them suggest that running some other code in background should be the reason for this. However I don't have any code running in background.
How should I fix this?
This is my code where I run camera
UIImagePickerController *photoPicker = [[UIImagePickerController alloc] init];
photoPicker.delegate = self;
photoPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:photoPicker animated:YES completion:NULL];
About 5 months ago my team discovered a memory leak with UIImageViewController in iOS7. Each instantiation slowed down the app exponentially (i.e. first alloc-init had a 1 second delay, second had a 2 second delay, third had a 5 second delay). Eventually, we were having 30-60 delays (similar to what you're experiencing).
We resolved the issue by subclassing UIImagePickerController and making it a Singleton. That way it was only ever initialized once. Now our delay is minimal and we avoid the leak. If subclassing isn't an option, try a class property in your viewController and just lazy load it like so.
-(UIImagePickerController *)imagePicker{
if(!_imagePicker){
_imagePicker = [[UIImagePickerController alloc]init];
_imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
}
return _imagePicker;
}
Then you can just call it later like:
[self presentViewController:self.imagePicker animated:YES completion:nil];
Had this myself - it happens if something is running on the main dispatch thread - are you resizing images by any chance?
It puts the preview onto the main thread and if something is using it, you get a black screen. It's a bug and the workaround is to either take over the main thread or to disable the photo picker until the queue is free
This Should work for you:
- (void)cameraViewPickerController:(UIImagePickerController *)picker
{
[self startCameraControllerFromViewController: picker
usingDelegate: self];
}
- (BOOL) startCameraControllerFromViewController: (UIViewController*) controller
usingDelegate: (id <UIImagePickerControllerDelegate,
UINavigationControllerDelegate>) delegate {
if (([UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypeCamera] == NO)
|| (delegate == nil)
|| (controller == nil))
return NO;
UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init];
cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera;
// Displays a control that allows the user to choose movie capture
cameraUI.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeImage, (NSString *) kUTTypeMovie,nil];
// Hides the controls for moving & scaling pictures, or for
// trimming movies. To instead show the controls, use YES.
cameraUI.allowsEditing = NO;
cameraUI.delegate = delegate;
[controller presentViewController:cameraUI animated:YES completion:nil];
return YES;
}
I'm trying to make multiple buttons fall down the screen all at once, at different speeds. But when I have my if statement check if it passed through the value, all the other buttons disappear with it. I'm also incrementing the score to go -1 each time a button passes through the Y value. Any help is appreciated, thanks.
- (void)b1Fall
{
b1.center = CGPointMake(b1.center.x, b1.center.y+6);
if (b1.center.y >= 506) {
[self updateScore];
b1.center = CGPointMake(44, 11);
}
}
- (void)b2Fall
{
b2.center = CGPointMake(b2.center.x, b2.center.y+7);
if (b2.center.y >= 506) {
[self updateScore];
b2.center = CGPointMake(160, 11);
}
}
- (void)b3Fall
{
b3.center = CGPointMake(b3.center.x, b3.center.y+8);
if (b3.center.y >= 506) {
[self updateScore];
b3.center = CGPointMake(276, 11);
}
}
- (void)updateScore
{
healthLabel.text = [NSString stringWithFormat:#"%d", [healthLabel.text intValue]-1];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// REMOVE AFTER TESTING
b1Timer = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:#selector(b1Fall) userInfo:nil repeats:true];
b2Timer = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:#selector(b2Fall) userInfo:nil repeats:true];
b2Timer = [NSTimer scheduledTimerWithTimeInterval:0.02 target:self selector:#selector(b3Fall) userInfo:nil repeats:true];
}
A few things:
1.) Put these animations in viewDidAppear instead of viewDidLoad - you want the animation to begin when the user is actually looking at the buttons, not when the view is loaded into memory, where the user may not be able to see it (viewDidLoad).
2.) Don't use NSTimer for animations, use this:
[UIView animateWithDuration:0.5
delay:1.0
options: UIViewAnimationCurveEaseOut
animations:^{
}
completion:^(BOOL finished){
// loop your animation here.
}];
3.) If you want to make a game, I don't recommend using this approach. All animations using UIKit are going to perform on the main thread and block the user flow. What you want is a framework like Cocos2D where the animations are doing in the GPU and ASYNC game logic is readily supported. UIKit isn't a good choice for game development in general.