I want to change the picture of my custom UIImageView Subclass by a timer. But it doesn't work. Can you help me?
This is my code:
-(id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self update];
}
return self;
}
-(void)update {
self.image = [UIImage imageNamed:#"Green.png"];
[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:#selector(change) userInfo:nil repeats:YES];
}
-(void)change {
self.image = [UIImage imageNamed:#"Red.png"];
}
Thanks!
use image property also to assign any image to imageView small rectification see below code.
Also do not give variable name same as its class property.
-(void)update {
self.image.image = [UIImage imageNamed:#"Green.png"];
[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:#selector(change) userInfo:nil repeats:YES];
}
-(void)change {
self.image.image = [UIImage imageNamed:#"Red.png"];
}
self.image.image peoperty added here
Edit:
change your property from UIImage to UIImageView like see below
#property (strong, nonatomic) IBOutlet UIImageView *image;
.h Header file
#import <UIKit/UIKit.h>
#interface orientation : UIViewController
#property (strong, nonatomic) IBOutlet UIImageView *image;
#end
.m Message file
#import "orientation.h"
#interface orientation ()
#end
#implementation orientation
- (void)viewDidLoad {
[super viewDidLoad];
[self update];
// Do any additional setup after loading the view.
}
-(void)update {
self.image.image = [UIImage imageNamed:#"investment1.png"];
[NSTimer scheduledTimerWithTimeInterval:5 target:self selector:#selector(change) userInfo:nil repeats:YES];
}
-(void)change {
self.image.image = [UIImage imageNamed:#"logout.png"];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Related
UIButton in my view does not respond when I click it. Some one figure
out what I am doing wrong? Here is my entire code:
MyView.h
#interface Myview : UIView
#end
MyView.m
#import "MyView.h"
- (init){
self = [super init];
if(self)
[self createButton];
return self;
}
- (void) createButton{
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(100,100,100,50)];
[button setTitle:#"Go" forState:UIControlStateNormal];
[button addTarget:self
`action:#selector(goAction)
forControlEvents:UIControlEventTouchUpInside];
[self addSubview:button];
}
- (void) goAction{
NSString *test = #"Some text";
}
MyViewController.m
- (id) init{
self = [super init];
if (self) {
MyView *myview = [[MyView alloc] init];
[self.view addSubview:myview];
}
return self;
}`
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
ViewController.m
#import "ViewController.h"
#import "MyViewController.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
MyViewController *myTestView = [[MyViewController alloc] init];
[self.view addSubview:myTestView.view];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
The reason why clicks does not work is that you don't set frame of MyView
This way it works (although I still don't understand why you need to add one ViewController into another)
#implementation MyViewController
- (instancetype)init
{
self = [super init];
if (self) {
MyView *myview = [[MyView alloc] init];
myview.frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.width);
[self.view addSubview:myview];
}
return self;
}
I have created a timer that is fired after 10.0 seconds and calls targetMethod: on self, which is a pointer to the NSTimer instance.This timer should only work when its associated viewcontroller screen is in the view.I have stopped the timer while loading .xib file called PhotoView.xib because timer blocks the UI. But I don't know how to start the timer again when PhotoView.xib is removed/dismissed from the Viewcontroller.
Can someone please tell me how to restart the timer(of parentViewcontroller) when .xib is dismissed from parentViewcontroller?
SampleView.h
#import <UIKit/UIKit.h>
#interface SampleView : UIView
#property(nonatomic,retain)IBOutlet UIView* view;
#property(nonatomic,retain)IBOutlet UIImageView* imageview;
#property(nonatomic,retain)IBOutlet UIButton* dismissButton;
#end
SampleView.m
#import "GroupPhotoView.h"
#implementation SampleView
#synthesize imageview,view,dismissButton;
-(IBAction) dismissView: (id) sender{
[self removeFromSuperview];
}
#end
SampleViewController.h
#import <UIKit/UIKit.h>
#interface SampleViewController : UIViewController
#property(nonatomic,retain)NSTimer *timer;
#end
SampleViewController.m
#import "SampleViewController.h"
#interface SampleViewController ()
#end
#implementation SampleViewController
#synthesize timer;
- (void)viewDidLoad {
[super viewDidLoad];
}
-(void)viewDidAppear:(BOOL)animated{
self.timer=[NSTimer scheduledTimerWithTimeInterval:10 target:self selector:#selector(sampleMethod:) userInfo:nil repeats:YES];
}
-(void)viewWillDisappear:(BOOL)animated{
//stop the timer when SampleVC is not in the view
if ([self.timer isValid])
{
[self.timer invalidate];
self.timer=nil;
}
}
- (IBAction)displayAction:(id)sender
{
[self loadSampleImage];
}
-(void)loadSampleImage:(UIImage*)aImage{
if ([self.timer isValid])
{
[self.timer invalidate];
self.timer=nil;
}
SampleView *customView =(SampleView *)[[[NSBundle mainBundle] loadNibNamed:#"PhotoView" owner:self options:nil] objectAtIndex:0];
customView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.8];
customView.imageview.image=[UIImage imageNamed:#"cs"];
[customView setFrame:self.view.frame];
[self.navigationController.view addSubview:customView];
}
}
#end
Thanks in advance.
You can use Delegate to restart NSTimer again. A delegate allows one object to send messages to another object when an event happens. A delegate is use for similar problem when object A calls to object B but once action completed A should know that B has completed the task and take necessary action.
Create SampleView :
// Delegate to respond back in SampleView.m
id <SampleView> _delegate;
// OR in SampleView.h
#property (strong, nonatomic) id _delegate;
After that add action completed call in SampleView.m :
-(IBAction) dismissView: (id) sender{
[self removeFromSuperview];
[_delegate startTimer];
}
Add method start Timer in SampleViewController.m:
customView.delegate = self;
-(void)startTimer
{
self.timer=[NSTimer scheduledTimerWithTimeInterval:10 target:self selector:#selector(sampleMethod:) userInfo:nil repeats:YES];
}
It will start timer again after .xib is dismissed from parentViewcontroller.
I am creating progress view by using CALayer by following
Header class
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#interface ProgressBar : UIView
#property (strong, nonatomic) CALayer *subLayer;
#property (nonatomic) CGFloat progress;
#end
Implementation class
#implementation ProgressBar
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.progress = 0;
self.backgroundColor = [UIColor whiteColor];
self.subLayer = [CALayer layer];
self.subLayer.frame = self.bounds;
self.subLayer.backgroundColor = [UIColor orangeColor].CGColor;
[self.layer addSublayer:self.subLayer];
}
return self;
}
- (void)setProgress:(CGFloat)value {
NSLog(#"what is going on here");
if (self.progress != value) {
self.progress = value;
[self setNeedsLayout];
}
}
- (void)layoutSubviews {
CGRect rect = [self.subLayer frame];
rect.size.width = CGRectGetWidth([self bounds]) * self.progress;
[self.subLayer setFrame:rect];
}
In my viewcontroller, I am doing
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.pBar = [[ProgressBar alloc] initWithFrame:CGRectMake(0, 50, 320, 10)];
[self.view addSubview:self.pBar];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)click:(id)sender {
[self.pBar setProgress:.8];
}
When (IBAction)click is fired, I am getting into the infinitive loop like the picture below
Does anyone know what I am getting into this loop. Please advice me on this issue. Thanks
The problem is that your setProgress: method calls the setProgress: method - recursion.
- (void)setProgress:(CGFloat)value {
NSLog(#"what is going on here");
if (self.progress != value) {
self.progress = value; // <-- This calls [self setProgress:value]
[self setNeedsLayout];
}
}
Change the bad line to:
_progress = value;
Setting the ivar directly is always required when you implement the setter method of a property.
I have a custom view that I'm using in a xib file. I load the view and add it to a window. It adds the view just fine as I can see the default text of the labels in the view, but when I try to change the label with a method call, it doesn't change the text.
The custom view isn't anything to fancy, just draws a rounded, transparent background.
NotificationView.h
#import <Cocoa/Cocoa.h>
#interface NotificationView : NSView
#property (weak) IBOutlet NSTextField *primaryLabel;
#property (weak) IBOutlet NSTextField *secondaryLabel;
#property (weak) IBOutlet NSTextField *identifierLabel;
#end
NotificationView.m
#implementation NotificationView
#synthesize primaryLabel;
#synthesize secondaryLabel;
#synthesize identifierLabel;
- (id) initWithFrame:(NSRect)frameRect
{
self = [super initWithFrame:frameRect];
if (self)
{
return self;
}
return nil;
}
- (void)drawRect:(NSRect)dirtyRect
{
NSColor *bgColor = [NSColor colorWithCalibratedWhite:0.0 alpha:0.6];
NSRect rect = NSMakeRect([self bounds].origin.x + 3, [self bounds].origin.y + 3, [self bounds].size.width - 6, [self bounds].size.height - 6);
NSBezierPath *path = [NSBezierPath bezierPathWithRoundedRect:rect xRadius:5.0 yRadius:5.0];
[path addClip];
NSShadow *shadow = [[NSShadow alloc] init];
[shadow setShadowColor:[NSColor redColor]];
[shadow setShadowBlurRadius:2.0f];
[shadow setShadowOffset:NSMakeSize(0.f, -1.f)];
[shadow set];
[bgColor set];
NSRectFill(rect);
[super drawRect:dirtyRect];
}
#end
In the xib I have a custom view set to the type NotificationView. I've added 3 labels to the view and connected them to the above IBOutlets. (I ctrl-click & drag from the label to the .h file to make the connection.)
I'm loading the view and adding it to a window with the following method. It looks through an array of windows, if an existing match is found it used that window, if not it creates a new window.
- (void) popupNotificationWithTag:(NSString *)tag fade:(double)msFade lineOne:(NSString *)lineOneText lineTwo:(NSString *)lineTwoText
{
NotificationWindow *notificationWindow;
NotificationWindow *tmpWindow;
NSEnumerator *enumerator;
// Walk the notification windows in the array
enumerator = [self.notificationWindows objectEnumerator];
if(enumerator)
{
while((tmpWindow = [enumerator nextObject]))
{
if([tmpWindow.tag isEqualToString:tag])
{
notificationWindow = tmpWindow;
}
}
}
// Make a new notification window
if (!notificationWindow)
{
int width = [[NSScreen mainScreen] frame].size.width;
int height = [[NSScreen mainScreen] frame].size.height;
notificationWindow = [[NotificationWindow alloc] initWithRect:NSMakeRect(width - 420, height - 130, 400, 100)];
NSNib *nib = [[NSNib alloc] initWithNibNamed:#"Notification" bundle: nil];
NSArray *objects;
[nib instantiateNibWithOwner:self topLevelObjects:&objects];
for (id obj in objects) {
if ([[obj class] isSubclassOfClass:[NSView class]])
[notificationWindow setContentView:obj];
}
[notificationWindow setTag:tag];
[self.notificationWindows addObject:notificationWindow];
}
// Display window
[notificationWindow makeKeyAndOrderFront:nil];
[notificationWindow display];
notificationWindow.fadeOut = msFade;
[notificationWindow setPrimaryText:lineOneText];
[notificationWindow setSecondaryText:lineTwoText];
[notificationWindow setIdentifierText:tag];
}
The window class is NotificationWindow.h
#import <Foundation/Foundation.h>
#interface NotificationWindow : NSWindow
#property (nonatomic, strong) NSString *tag;
#property (nonatomic) double fadeOut;
- (id)initWithRect:(NSRect)contentRect;
- (void) setPrimaryText:(NSString *)text;
- (void) setSecondaryText:(NSString *)text;
- (void) setIdentifierText:(NSString *)text;
#end
NotificationWindow.m
#import "NotificationWindow.h"
#import "NotificationView.h"
//===========================================================================================================================
// Private call properties and methods
//===========================================================================================================================
#interface NotificationWindow()
#property (nonatomic,strong) NSTimer *timerFade;
- (void) timerFadeFired;
#end
//===========================================================================================================================
//===========================================================================================================================
#implementation NotificationWindow
//===========================================================================================================================
// Property Getters and Setters
//===========================================================================================================================
#synthesize tag = _tag;
#synthesize fadeOut = _fadeOut;
#synthesize timerFade = _timerFade;
//===========================================================================================================================
// Public methods
//===========================================================================================================================
- (id)initWithRect:(NSRect)contentRect
{
if (self = [super initWithContentRect:contentRect
styleMask:NSBorderlessWindowMask
backing:NSBackingStoreBuffered
defer:NO]) {
[self setLevel: NSScreenSaverWindowLevel];
[self setBackgroundColor: [NSColor clearColor]];
[self setAlphaValue: 1.0];
[self setOpaque: NO];
[self setHasShadow: NO];
[self setIgnoresMouseEvents: YES];
[self setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces];
[self orderFront: NSApp];
self.fadeOut = -1;
// Start our timer to deal with fadeing the window
self.timerFade = [NSTimer scheduledTimerWithTimeInterval:0.001
target:self
selector:#selector(timerFadeFired)
userInfo:nil
repeats:YES];
return self;
}
return nil;
}
- (BOOL) canBecomeKeyWindow
{
return YES;
}
- (void) display
{
[super display];
[self setAlphaValue:1.0];
}
- (void) setPrimaryText:(NSString *)text
{
NotificationView *view = self.contentView;
view.primaryLabel.stringValue = text;
}
- (void) setSecondaryText:(NSString *)text
{
NotificationView *view = self.contentView;
view.secondaryLabel.stringValue = text;
}
- (void) setIdentifierText:(NSString *)text
{
NotificationView *view = self.contentView;
view.identifierLabel.stringValue = text;
}
//===========================================================================================================================
// Private methods
//===========================================================================================================================
- (void) timerFadeFired
{
[self orderFront:NSApp];
if (self.fadeOut > 0)
{
self.fadeOut--;
}
else if (self.fadeOut == 0)
{
if (self.alphaValue > 0)
self.alphaValue -= 0.002;
else
self.fadeOut = -1;
}
}
#end
So I assume I'm doing something wrong connecting the labels to the IBOutlets, but I can't figure out what. I suppose I could create the view in code, but I was trying to be good and use the interface builder.
I'm in XCode 4.2.1.
I try to build a endless scrolling UIScrollView. So far I took the apple sample "StreetScroller". So all I do is setting the contentOffset back when it reaches the end of the scroll view.
Override -layoutSubviews of the UIScrollView:
- (void)layoutSubviews
{
CGFloat contentWidth = [self contentSize].width;
CGPoint contentOffset = [self contentOffset];
CGFloat centerOffsetX = (contentWidth - [self bounds].size.width) / 2.0;
CGFloat distanceFromCenter = contentOffset.x - centerOffsetX;
if (ABS(distanceFromCenter) > (contentWidth / 4.0)) {
contentOffset = CGPointMake(centerOffsetX, contentOffset.y);
[super setContentOffset:contentOffset];
}
}
Now on iOS 5 this works like a charm. But on iOS 4.3 it's not working. As soon as I call [super setContentOffset:contentOffset] it stoops scrolling because next time -layoutSubviews get's called the [self contentOffset] does not return the contentOffset that was set.
I know there are a lot a questions about infinite UIScrollViews, but one of these has fixed this problem!
Try this One. This Code is Working Properly for me on iOS 4.3
RootViewController.h
#class ViewControllerForDuplicateEndCaps;
#interface RootViewController : UIViewController {
ViewControllerForDuplicateEndCaps *viewControllerForDuplicateEndCaps;
}
#property (nonatomic, retain) ViewControllerForDuplicateEndCaps *viewControllerForDuplicateEndCaps;
- (IBAction)loadScrollViewWithDuplicateEndCaps:(id)sender;
#end
RootViewController.m
#import "RootViewController.h"
#import "ViewControllerForDuplicateEndCaps.h"
#import "InfiniteScrollViewAppDelegate.h"
#implementation RootViewController
#synthesize viewControllerForDuplicateEndCaps;
- (IBAction)loadScrollViewWithDuplicateEndCaps:(id)sender {
InfiniteScrollViewAppDelegate *delegate = (InfiniteScrollViewAppDelegate*)[[UIApplication sharedApplication] delegate];
if(self.viewControllerForDuplicateEndCaps == nil) {
ViewControllerForDuplicateEndCaps *temp = [[ViewControllerForDuplicateEndCaps alloc] initWithNibName:#"ViewControllerForDuplicateEndCaps" bundle:nil];
self.viewControllerForDuplicateEndCaps = temp;
[temp release];
}
UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStyleBordered target:nil action:nil];
self.navigationItem.backBarButtonItem = backButton;
[backButton release];
[delegate.navigationController pushViewController:self.viewControllerForDuplicateEndCaps animated:YES];
}
- (void)dealloc {
[scrollView release];
[super dealloc];
}
#end
ViewControllerForDuplicateEndCaps.h
#import <UIKit/UIKit.h>
#interface ViewControllerForDuplicateEndCaps : UIViewController <UIScrollViewDelegate> {
IBOutlet UIScrollView *scrollView;
}
#property (nonatomic, retain) UIScrollView *scrollView;
- (void)addImageWithName:(NSString*)imageString atPosition:(int)position;
#end
ViewControllerForDuplicateEndCaps.m
#import "ViewControllerForDuplicateEndCaps.h"
#implementation ViewControllerForDuplicateEndCaps
#synthesize scrollView;
- (void)viewDidLoad {
[super viewDidLoad];
// add the last image (image4) into the first position
[self addImageWithName:#"image4.jpg" atPosition:0];
// add all of the images to the scroll view
for (int i = 1; i < 5; i++) {
[self addImageWithName:[NSString stringWithFormat:#"image%i.jpg",i] atPosition:i];
}
// add the first image (image1) into the last position
[self addImageWithName:#"image1.jpg" atPosition:5];
scrollView.contentSize = CGSizeMake(1920, 416);
[scrollView scrollRectToVisible:CGRectMake(320,0,320,416) animated:NO];
}
- (void)addImageWithName:(NSString*)imageString atPosition:(int)position {
// add image to scroll view
UIImage *image = [UIImage imageNamed:imageString];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.frame = CGRectMake(position*320, 0, 320, 416);
[scrollView addSubview:imageView];
[imageView release];
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)sender {
NSLog(#"%f",scrollView.contentOffset.x);
// The key is repositioning without animation
if (scrollView.contentOffset.x == 0) {
// user is scrolling to the left from image 1 to image 4
// reposition offset to show image 4 that is on the right in the scroll view
[scrollView scrollRectToVisible:CGRectMake(1280,0,320,416) animated:NO];
}
else if (scrollView.contentOffset.x == 1600) {
// user is scrolling to the right from image 4 to image 1
// reposition offset to show image 1 that is on the left in the scroll view
[scrollView scrollRectToVisible:CGRectMake(320,0,320,416) animated:NO];
}
}
- (void)dealloc {
[scrollView release];
[super dealloc];
}
#end