infinite carousel with objective-c - objective-c

I'm facing 2 problems with my code and i would like to see if somebody can help me to fix it?
here is my code:
#import "ViewController.h"
#interface ViewController () {
#private NSInteger index;
#private NSInteger iterations;
#private UIButton* buttons[6];
#private CGPoint centers[6];
#private CGRect bounds[6];
#private CGFloat opacities[6];
#private CGFloat opacitieOffsets[6];
#private CGPoint centerOffsets[6];
#private CGRect boundOffsets[6];
#private NSString* titles[6];
}
#property (strong, nonatomic) NSTimer *timer;
#end
#implementation ViewController
#synthesize Button1;
#synthesize Button2;
#synthesize Button3;
#synthesize Button4;
#synthesize Button5;
#synthesize Button6;
#synthesize TitleLabel;
- (void)viewDidLoad
{
[super viewDidLoad];
buttons[0] = Button1;
titles[0] = #"btnTitle1";
buttons[1] = Button2;
titles[1] = #"btnTitle2";
buttons[2] = Button3;
titles[2] = #"btnTitle3";
buttons[3] = Button4;
titles[3] = #"btnTitle4";
buttons[4] = Button5;
titles[4] = #"btnTitle5";
buttons[5] = Button6;
titles[5] = #"btnTitle6";
for (NSInteger i = 0; i < 6; i++)
{
centers[i] = buttons[i].center;
bounds[i] = buttons[i].bounds;
opacities[i] = buttons[i].alpha;
}
}
- (void)viewDidUnload
{
[self stopAnimation];
[self setButton1:nil];
[self setButton2:nil];
[self setButton3:nil];
[self setButton4:nil];
[self setButton5:nil];
[self setButton6:nil];
[self setTitleLabel:nil];
[super viewDidUnload];
}
/////////////////////////////////////////////////////
- (IBAction)swipeLeft:(UISwipeGestureRecognizer *)sender {
[self stopAnimation];
buttons[index].enabled = NO;
{
TitleLabel.text = #"";
index = [self next:index];
[self startAnimation];
}
}
- (IBAction)swipeRight:(UISwipeGestureRecognizer *)sender {
[self stopAnimation];
buttons[index].enabled = NO;
{
TitleLabel.text = #"";
index = [self back:index];
[self startAnimation];
}
}
///////////////////////////////////////////////////
- (void)startAnimation
{
[self prepareForUpdate];
[self.timer invalidate];
self.timer = [NSTimer scheduledTimerWithTimeInterval:0 target:self selector:#selector(update) userInfo:nil repeats:YES];
}
- (void)stopAnimation
{
[self.timer invalidate];
[self finalizeUpdate];
self.timer = nil;
}
- (void)prepareForUpdate
{
NSInteger i = 0;
NSInteger iter = index;
do
{
centerOffsets[iter] = CGPointMake
(
(centers[i].x - buttons[iter].center.x) / 30,
(centers[i].y - buttons[iter].center.y) / 30
);
boundOffsets[iter] = CGRectMake
(
(bounds[i].origin.x - buttons[iter].bounds.origin.x) / 30,
(bounds[i].origin.y - buttons[iter].bounds.origin.y) / 30,
(bounds[i].size.width - buttons[iter].bounds.size.width) / 30,
(bounds[i].size.height - buttons[iter].bounds.size.height) / 30
);
opacitieOffsets[iter] = (opacities[i] - buttons[iter].alpha) / 30;
i++;
iter = [self next:iter];
}
while ( iter != index);
iterations = 30;
}
- (void)update
{
if (iterations <= 1)
{
}
if (iterations > 0)
{
for (NSInteger i = 0; i < 6; i++)
{
buttons[i].center = CGPointMake
(
centerOffsets[i].x + buttons[i].center.x,
centerOffsets[i].y + buttons[i].center.y
);
buttons[i].bounds = CGRectMake
(
boundOffsets[i].origin.x + buttons[i].bounds.origin.x,
boundOffsets[i].origin.y + buttons[i].bounds.origin.y,
boundOffsets[i].size.width + buttons[i].bounds.size.width,
boundOffsets[i].size.height + buttons[i].bounds.size.height
);
buttons[i].alpha = buttons[i].alpha + opacitieOffsets[i];
}
iterations--;
}
else [self stopAnimation];
}
- (void)finalizeUpdate
{
NSInteger i = 0;
NSInteger iter = index;
do
{
buttons[iter].center = centers[i];
buttons[iter].bounds = bounds[i];
buttons[iter].alpha = opacities[i];
i++;
iter = [self next:iter];
}
while ( iter != index);
iterations = 0;
buttons[index].enabled = YES;
TitleLabel.text = titles[index];
}
- (NSInteger)back:(NSInteger) i
{
return i == 0 ? 5 : i - 1;
}
- (NSInteger)next:(NSInteger) i
{
return i == 5 ? 0 : i + 1;
}
i want to said that my code work, but need some adjustment or many probably!!
1) first problem it's that the carousel go left/right very slow, I change the time but i still haven't figure out??????
2) I can still see the buttons from the carousel when they rotating in the back, i set alpha to 0 but i can still see them????
I'm new to objective-c so sorry for my mistake, objective-c is very different than c++
help and advice please???

The following line is incorrect:
self.timer = [NSTimer scheduledTimerWithTimeInterval:0 target:self selector:#selector(update) userInfo:nil repeats:YES];
You are scheduling a timer to fire every 0 seconds, which is consuming the runloop by trying to execute continuously. You have to change that line to schedule the timer with a value greater than 0, for example:
self.timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:#selector(update) userInfo:nil repeats:YES];

Related

NSView drawRect not being called

This is my first time really using cocoa to make an application for mac. The only problem is that drawRect isn't being called at all. The real kicker is that it used to, but now it doesn't, and I have no idea what I did wrong. :/
I am setting 'setNeedsDisplay' but it refuses to work. As you can see, I have two debug prints in there, but only "DEBUG 1" is being called. Any ideas?
//ScrollingTextView.h:
//Adapted from http://stackoverflow.com/a/3233802/3438793
#import <Cocoa/Cocoa.h>
#interface ScrollingTextView : NSView {
NSTimer *scroller;
NSPoint point;
NSString *text;
NSString *tempText;
NSString *nextText;
CGFloat stringWidth;
NSInteger delay;
BOOL draw;
NSDictionary *fontDict;
NSFont *font;
BOOL isBigger;
}
#property (nonatomic, copy) NSString *text;
#property (nonatomic, copy) NSString *tempText;
#property (nonatomic, copy) NSString *nextText;
#property (nonatomic) NSInteger delay;
#property (nonatomic) BOOL draw;
#property (nonatomic) NSDictionary *fontDict;
#property (nonatomic) NSFont *font;
#property (nonatomic) BOOL isBigger;
#end
//ScrollingTextView.m
//Adapted from http://stackoverflow.com/a/3233802/3438793
#import "ScrollingTextView.h"
#implementation ScrollingTextView
#synthesize text;
#synthesize tempText;
#synthesize nextText;
#synthesize delay;
#synthesize draw;
#synthesize fontDict;
#synthesize font;
#synthesize isBigger;
- (void) setNextText:(NSString *)newText {
font = [NSFont fontWithName:#"Lucida Grande" size:15.0];
fontDict = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, [NSNumber numberWithFloat:1.0], NSBaselineOffsetAttributeName, nil];
if (text == nil) {
text = [newText copy];
} else {
nextText = [newText copy];
}
point = NSZeroPoint;
stringWidth = [newText sizeWithAttributes:fontDict].width;
if (stringWidth <= 163) {
NSString *size = [#"{" stringByAppendingString:[[NSString stringWithFormat:#"%f", stringWidth] stringByAppendingString:#", 22}"]];
[self setFrameSize:NSSizeFromString(size)];
isBigger = false;
} else {
isBigger = true;
}
if (text != nil) {
scroller = nil;
scroller = [NSTimer scheduledTimerWithTimeInterval:0.03 target:self selector:#selector(moveText:) userInfo:nil repeats:YES];
}
draw = false;
delay = 100;
}
- (void) moveText:(NSTimer *)timer {
point.x = point.x - 1.0f;
[self setNeedsDisplay:YES];
NSLog(#"DEBUG 1");
}
- (void)drawRect:(NSRect)dirtyRect {
// Drawing code here.
NSLog(#"DEBUG 2");
//NSLog([#"Next: " stringByAppendingString:nextText]);
//NSLog([#"Temp: " stringByAppendingString:tempText]);
//NSLog([#"Main: " stringByAppendingString:text]);
if (isBigger) {
if (draw) {
CGFloat pointX = dirtyRect.size.width + (-1*(dirtyRect.size.width - stringWidth)) + 30;
if (point.x < -1*pointX) {
point.x += pointX;
draw = false;
delay = 100;
text = tempText;
tempText = nil;
}
[text drawAtPoint:point withAttributes:fontDict];
if (point.x < 0) {
NSPoint otherPoint = point;
otherPoint.x += pointX;
if (tempText != nil) {
[tempText drawAtPoint:otherPoint withAttributes:fontDict];
} else {
[text drawAtPoint:otherPoint withAttributes:fontDict];
}
}
} else {
if (nextText != nil) {
tempText = nextText;
nextText = nil;
}
point.x = 0;
[text drawAtPoint:point withAttributes:fontDict];
if (delay <= 0) {
draw = true;
} else {
delay -= 1;
}
}
} else {
dirtyRect.size.width = stringWidth;
point.x = 0;
text = nextText;
[text drawAtPoint:point withAttributes:fontDict];
}
}
#end
EDIT: I added a line to "moveText" to see what "needsDisplay" was, and it turns out that "[self setNeedsDisplay:YES];" is doing nothing. Here is the line I added:
- (void) moveText:(NSTimer *)timer {
point.x = point.x - 1.0f;
[self setNeedsDisplay:YES];
NSLog([NSString stringWithFormat:#"%hhd", [self needsDisplay]]); //This one
}
It just prints 0

PDF ReaderViewController

Wondering if anyone could give an example of how to dowload files for use with this PDF Reader code? I am very new and have been hacking away at it but I think it's time for some experienced eyes. thanks!
//
// ReaderViewController.m
// Reader v2.6.0
/////////////////////////////
#import "ReaderConstants.h"
#import "ReaderViewController.h"
#import "ThumbsViewController.h"
#import "ReaderMainToolbar.h"
#import "ReaderMainPagebar.h"
#import "ReaderContentView.h"
#import "ReaderThumbCache.h"
#import "ReaderThumbQueue.h"
#import <MessageUI/MessageUI.h>
#interface ReaderViewController () <UIScrollViewDelegate, UIGestureRecognizerDelegate, MFMailComposeViewControllerDelegate,
ReaderMainToolbarDelegate, ReaderMainPagebarDelegate, ReaderContentViewDelegate, ThumbsViewControllerDelegate>
#end
#implementation ReaderViewController
{
ReaderDocument *document;
UIScrollView *theScrollView;
ReaderMainToolbar *mainToolbar;
ReaderMainPagebar *mainPagebar;
NSMutableDictionary *contentViews;
UIPrintInteractionController *printInteraction;
NSInteger currentPage;
CGSize lastAppearSize;
NSDate *lastHideTime;
BOOL isVisible;
}
#pragma mark Constants
#define PAGING_VIEWS 3
#define TOOLBAR_HEIGHT 44.0f
#define PAGEBAR_HEIGHT 48.0f
#define TAP_AREA_SIZE 48.0f
#pragma mark Properties
#synthesize delegate;
#pragma mark Support methods
- (void)updateScrollViewContentSize
{
NSInteger count = [document.pageCount integerValue];
if (count > PAGING_VIEWS) count = PAGING_VIEWS; // Limit
CGFloat contentHeight = theScrollView.bounds.size.height;
CGFloat contentWidth = (theScrollView.bounds.size.width * count);
theScrollView.contentSize = CGSizeMake(contentWidth, contentHeight);
}
- (void)updateScrollViewContentViews
{
[self updateScrollViewContentSize]; // Update the content size
NSMutableIndexSet *pageSet = [NSMutableIndexSet indexSet]; // Page set
[contentViews enumerateKeysAndObjectsUsingBlock: // Enumerate content views
^(id key, id object, BOOL *stop)
{
ReaderContentView *contentView = object; [pageSet addIndex:contentView.tag];
}
];
__block CGRect viewRect = CGRectZero; viewRect.size = theScrollView.bounds.size;
__block CGPoint contentOffset = CGPointZero; NSInteger page = [document.pageNumber integerValue];
[pageSet enumerateIndexesUsingBlock: // Enumerate page number set
^(NSUInteger number, BOOL *stop)
{
NSNumber *key = [NSNumber numberWithInteger:number]; // # key
ReaderContentView *contentView = [contentViews objectForKey:key];
contentView.frame = viewRect; if (page == number) contentOffset = viewRect.origin;
viewRect.origin.x += viewRect.size.width; // Next view frame position
}
];
if (CGPointEqualToPoint(theScrollView.contentOffset, contentOffset) == false)
{
theScrollView.contentOffset = contentOffset; // Update content offset
}
}
- (void)updateToolbarBookmarkIcon
{
NSInteger page = [document.pageNumber integerValue];
BOOL bookmarked = [document.bookmarks containsIndex:page];
[mainToolbar setBookmarkState:bookmarked]; // Update
}
- (void)showDocumentPage:(NSInteger)page
{
if (page != currentPage) // Only if different
{
NSInteger minValue; NSInteger maxValue;
NSInteger maxPage = [document.pageCount integerValue];
NSInteger minPage = 1;
if ((page < minPage) || (page > maxPage)) return;
if (maxPage <= PAGING_VIEWS) // Few pages
{
minValue = minPage;
maxValue = maxPage;
}
else // Handle more pages
{
minValue = (page - 1);
maxValue = (page + 1);
if (minValue < minPage)
{minValue++; maxValue++;}
else
if (maxValue > maxPage)
{minValue--; maxValue--;}
}
NSMutableIndexSet *newPageSet = [NSMutableIndexSet new];
NSMutableDictionary *unusedViews = [contentViews mutableCopy];
CGRect viewRect = CGRectZero; viewRect.size = theScrollView.bounds.size;
for (NSInteger number = minValue; number <= maxValue; number++)
{
NSNumber *key = [NSNumber numberWithInteger:number]; // # key
ReaderContentView *contentView = [contentViews objectForKey:key];
if (contentView == nil) // Create a brand new document content view
{
NSURL *fileURL = document.fileURL; NSString *phrase = document.password; // Document properties
contentView = [[ReaderContentView alloc] initWithFrame:viewRect fileURL:fileURL page:number password:phrase];
[theScrollView addSubview:contentView]; [contentViews setObject:contentView forKey:key];
contentView.message = self; [newPageSet addIndex:number];
}
else // Reposition the existing content view
{
contentView.frame = viewRect; [contentView zoomReset];
[unusedViews removeObjectForKey:key];
}
viewRect.origin.x += viewRect.size.width;
}
[unusedViews enumerateKeysAndObjectsUsingBlock: // Remove unused views
^(id key, id object, BOOL *stop)
{
[contentViews removeObjectForKey:key];
ReaderContentView *contentView = object;
[contentView removeFromSuperview];
}
];
unusedViews = nil; // Release unused views
CGFloat viewWidthX1 = viewRect.size.width;
CGFloat viewWidthX2 = (viewWidthX1 * 2.0f);
CGPoint contentOffset = CGPointZero;
if (maxPage >= PAGING_VIEWS)
{
if (page == maxPage)
contentOffset.x = viewWidthX2;
else
if (page != minPage)
contentOffset.x = viewWidthX1;
}
else
if (page == (PAGING_VIEWS - 1))
contentOffset.x = viewWidthX1;
if (CGPointEqualToPoint(theScrollView.contentOffset, contentOffset) == false)
{
theScrollView.contentOffset = contentOffset; // Update content offset
}
if ([document.pageNumber integerValue] != page) // Only if different
{
document.pageNumber = [NSNumber numberWithInteger:page]; // Update page number
}
NSURL *fileURL = document.fileURL; NSString *phrase = document.password; NSString *guid = document.guid;
if ([newPageSet containsIndex:page] == YES) // Preview visible page first
{
NSNumber *key = [NSNumber numberWithInteger:page]; // # key
ReaderContentView *targetView = [contentViews objectForKey:key];
[targetView showPageThumb:fileURL page:page password:phrase guid:guid];
[newPageSet removeIndex:page]; // Remove visible page from set
}
[newPageSet enumerateIndexesWithOptions:NSEnumerationReverse usingBlock: // Show previews
^(NSUInteger number, BOOL *stop)
{
NSNumber *key = [NSNumber numberWithInteger:number]; // # key
ReaderContentView *targetView = [contentViews objectForKey:key];
[targetView showPageThumb:fileURL page:number password:phrase guid:guid];
}
];
newPageSet = nil; // Release new page set
[mainPagebar updatePagebar]; // Update the pagebar display
[self updateToolbarBookmarkIcon]; // Update bookmark
currentPage = page; // Track current page number
}
}
- (void)showDocument:(id)object
{
[self updateScrollViewContentSize]; // Set content size
[self showDocumentPage:[document.pageNumber integerValue]];
document.lastOpen = [NSDate date]; // Update last opened date
isVisible = YES; // iOS present modal bodge
}
#pragma mark UIViewController methods
- (id)initWithReaderDocument:(ReaderDocument *)object
{
id reader = nil; // ReaderViewController object
if ((object != nil) && ([object isKindOfClass:[ReaderDocument class]]))
{
if ((self = [super initWithNibName:nil bundle:nil])) // Designated initializer
{
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver:self selector:#selector(applicationWill:) name:UIApplicationWillTerminateNotification object:nil];
[notificationCenter addObserver:self selector:#selector(applicationWill:) name:UIApplicationWillResignActiveNotification object:nil];
[object updateProperties]; document = object; // Retain the supplied ReaderDocument object for our use
[ReaderThumbCache touchThumbCacheWithGUID:object.guid]; // Touch the document thumb cache directory
reader = self; // Return an initialized ReaderViewController object
}
}
return reader;
}
- (void)viewDidLoad
{
[super viewDidLoad];
assert(document != nil); // Must have a valid ReaderDocument
self.view.backgroundColor = [UIColor scrollViewTexturedBackgroundColor];
CGRect viewRect = self.view.bounds; // View controller's view bounds
theScrollView = [[UIScrollView alloc] initWithFrame:viewRect]; // All
theScrollView.scrollsToTop = NO;
theScrollView.pagingEnabled = YES;
theScrollView.delaysContentTouches = NO;
theScrollView.showsVerticalScrollIndicator = NO;
theScrollView.showsHorizontalScrollIndicator = NO;
theScrollView.contentMode = UIViewContentModeRedraw;
theScrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
theScrollView.backgroundColor = [UIColor clearColor];
theScrollView.userInteractionEnabled = YES;
theScrollView.autoresizesSubviews = NO;
theScrollView.delegate = self;
[self.view addSubview:theScrollView];
CGRect toolbarRect = viewRect;
toolbarRect.size.height = TOOLBAR_HEIGHT;
mainToolbar = [[ReaderMainToolbar alloc] initWithFrame:toolbarRect document:document]; // At top
mainToolbar.delegate = self;
[self.view addSubview:mainToolbar];
CGRect pagebarRect = viewRect;
pagebarRect.size.height = PAGEBAR_HEIGHT;
pagebarRect.origin.y = (viewRect.size.height - PAGEBAR_HEIGHT);
mainPagebar = [[ReaderMainPagebar alloc] initWithFrame:pagebarRect document:document]; // At bottom
mainPagebar.delegate = self;
[self.view addSubview:mainPagebar];
UITapGestureRecognizer *singleTapOne = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleSingleTap:)];
singleTapOne.numberOfTouchesRequired = 1; singleTapOne.numberOfTapsRequired = 1; singleTapOne.delegate = self;
[self.view addGestureRecognizer:singleTapOne];
UITapGestureRecognizer *doubleTapOne = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTap:)];
doubleTapOne.numberOfTouchesRequired = 1; doubleTapOne.numberOfTapsRequired = 2; doubleTapOne.delegate = self;
[self.view addGestureRecognizer:doubleTapOne];
UITapGestureRecognizer *doubleTapTwo = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(handleDoubleTap:)];
doubleTapTwo.numberOfTouchesRequired = 2; doubleTapTwo.numberOfTapsRequired = 2; doubleTapTwo.delegate = self;
[self.view addGestureRecognizer:doubleTapTwo];
[singleTapOne requireGestureRecognizerToFail:doubleTapOne]; // Single tap requires double tap to fail
contentViews = [NSMutableDictionary new]; lastHideTime = [NSDate date];
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if (CGSizeEqualToSize(lastAppearSize, CGSizeZero) == false)
{
if (CGSizeEqualToSize(lastAppearSize, self.view.bounds.size) == false)
{
[self updateScrollViewContentViews]; // Update content views
}
lastAppearSize = CGSizeZero; // Reset view size tracking
}
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if (CGSizeEqualToSize(theScrollView.contentSize, CGSizeZero)) // First time
{
[self performSelector:#selector(showDocument:) withObject:nil afterDelay:0.02];
}
#if (READER_DISABLE_IDLE == TRUE) // Option
[UIApplication sharedApplication].idleTimerDisabled = YES;
#endif // end of READER_DISABLE_IDLE Option
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
lastAppearSize = self.view.bounds.size; // Track view size
#if (READER_DISABLE_IDLE == TRUE) // Option
[UIApplication sharedApplication].idleTimerDisabled = NO;
#endif // end of READER_DISABLE_IDLE Option
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (void)viewDidUnload
{
#ifdef DEBUG
NSLog(#"%s", __FUNCTION__);
#endif
mainToolbar = nil; mainPagebar = nil;
theScrollView = nil; contentViews = nil; lastHideTime = nil;
lastAppearSize = CGSizeZero; currentPage = 0;
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
if (isVisible == NO) return; // iOS present modal bodge
if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
{
if (printInteraction != nil) [printInteraction dismissAnimated:NO];
}
}
- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation duration:(NSTimeInterval)duration
{
if (isVisible == NO) return; // iOS present modal bodge
[self updateScrollViewContentViews]; // Update content views
lastAppearSize = CGSizeZero; // Reset view size tracking
}
/*
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
//if (isVisible == NO) return; // iOS present modal bodge
//if (fromInterfaceOrientation == self.interfaceOrientation) return;
}
*/
- (void)didReceiveMemoryWarning
{
#ifdef DEBUG
NSLog(#"%s", __FUNCTION__);
#endif
[super didReceiveMemoryWarning];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark UIScrollViewDelegate methods
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
__block NSInteger page = 0;
CGFloat contentOffsetX = scrollView.contentOffset.x;
[contentViews enumerateKeysAndObjectsUsingBlock: // Enumerate content views
^(id key, id object, BOOL *stop)
{
ReaderContentView *contentView = object;
if (contentView.frame.origin.x == contentOffsetX)
{
page = contentView.tag; *stop = YES;
}
}
];
if (page != 0) [self showDocumentPage:page]; // Show the page
}
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
[self showDocumentPage:theScrollView.tag]; // Show page
theScrollView.tag = 0; // Clear page number tag
}
#pragma mark UIGestureRecognizerDelegate methods
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)recognizer shouldReceiveTouch:(UITouch *)touch
{
if ([touch.view isKindOfClass:[UIScrollView class]]) return YES;
return NO;
}
#pragma mark UIGestureRecognizer action methods
- (void)decrementPageNumber
{
if (theScrollView.tag == 0) // Scroll view did end
{
NSInteger page = [document.pageNumber integerValue];
NSInteger maxPage = [document.pageCount integerValue];
NSInteger minPage = 1; // Minimum
if ((maxPage > minPage) && (page != minPage))
{
CGPoint contentOffset = theScrollView.contentOffset;
contentOffset.x -= theScrollView.bounds.size.width; // -= 1
[theScrollView setContentOffset:contentOffset animated:YES];
theScrollView.tag = (page - 1); // Decrement page number
}
}
}
- (void)incrementPageNumber
{
if (theScrollView.tag == 0) // Scroll view did end
{
NSInteger page = [document.pageNumber integerValue];
NSInteger maxPage = [document.pageCount integerValue];
NSInteger minPage = 1; // Minimum
if ((maxPage > minPage) && (page != maxPage))
{
CGPoint contentOffset = theScrollView.contentOffset;
contentOffset.x += theScrollView.bounds.size.width; // += 1
[theScrollView setContentOffset:contentOffset animated:YES];
theScrollView.tag = (page + 1); // Increment page number
}
}
}
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer
{
if (recognizer.state == UIGestureRecognizerStateRecognized)
{
CGRect viewRect = recognizer.view.bounds; // View bounds
CGPoint point = [recognizer locationInView:recognizer.view];
CGRect areaRect = CGRectInset(viewRect, TAP_AREA_SIZE, 0.0f); // Area
if (CGRectContainsPoint(areaRect, point)) // Single tap is inside the area
{
NSInteger page = [document.pageNumber integerValue]; // Current page #
NSNumber *key = [NSNumber numberWithInteger:page]; // Page number key
ReaderContentView *targetView = [contentViews objectForKey:key];
id target = [targetView processSingleTap:recognizer]; // Target
if (target != nil) // Handle the returned target object
{
if ([target isKindOfClass:[NSURL class]]) // Open a URL
{
NSURL *url = (NSURL *)target; // Cast to a NSURL object
if (url.scheme == nil) // Handle a missing URL scheme
{
NSString *www = url.absoluteString; // Get URL string
if ([www hasPrefix:#"www"] == YES) // Check for 'www' prefix
{
NSString *http = [NSString stringWithFormat:#"http://%#", www];
url = [NSURL URLWithString:http]; // Proper http-based URL
}
}
if ([[UIApplication sharedApplication] openURL:url] == NO)
{
#ifdef DEBUG
NSLog(#"%s '%#'", __FUNCTION__, url); // Bad or unknown URL
#endif
}
}
else // Not a URL, so check for other possible object type
{
if ([target isKindOfClass:[NSNumber class]]) // Goto page
{
NSInteger value = [target integerValue]; // Number
[self showDocumentPage:value]; // Show the page
}
}
}
else // Nothing active tapped in the target content view
{
if ([lastHideTime timeIntervalSinceNow] < -0.75) // Delay since hide
{
if ((mainToolbar.hidden == YES) || (mainPagebar.hidden == YES))
{
[mainToolbar showToolbar]; [mainPagebar showPagebar]; // Show
}
}
}
return;
}
CGRect nextPageRect = viewRect;
nextPageRect.size.width = TAP_AREA_SIZE;
nextPageRect.origin.x = (viewRect.size.width - TAP_AREA_SIZE);
if (CGRectContainsPoint(nextPageRect, point)) // page++ area
{
[self incrementPageNumber]; return;
}
CGRect prevPageRect = viewRect;
prevPageRect.size.width = TAP_AREA_SIZE;
if (CGRectContainsPoint(prevPageRect, point)) // page-- area
{
[self decrementPageNumber]; return;
}
}
}
- (void)handleDoubleTap:(UITapGestureRecognizer *)recognizer
{
if (recognizer.state == UIGestureRecognizerStateRecognized)
{
CGRect viewRect = recognizer.view.bounds; // View bounds
CGPoint point = [recognizer locationInView:recognizer.view];
CGRect zoomArea = CGRectInset(viewRect, TAP_AREA_SIZE, TAP_AREA_SIZE);
if (CGRectContainsPoint(zoomArea, point)) // Double tap is in the zoom area
{
NSInteger page = [document.pageNumber integerValue]; // Current page #
NSNumber *key = [NSNumber numberWithInteger:page]; // Page number key
ReaderContentView *targetView = [contentViews objectForKey:key];
switch (recognizer.numberOfTouchesRequired) // Touches count
{
case 1: // One finger double tap: zoom ++
{
[targetView zoomIncrement]; break;
}
case 2: // Two finger double tap: zoom --
{
[targetView zoomDecrement]; break;
}
}
return;
}
CGRect nextPageRect = viewRect;
nextPageRect.size.width = TAP_AREA_SIZE;
nextPageRect.origin.x = (viewRect.size.width - TAP_AREA_SIZE);
if (CGRectContainsPoint(nextPageRect, point)) // page++ area
{
[self incrementPageNumber]; return;
}
CGRect prevPageRect = viewRect;
prevPageRect.size.width = TAP_AREA_SIZE;
if (CGRectContainsPoint(prevPageRect, point)) // page-- area
{
[self decrementPageNumber]; return;
}
}
}
#pragma mark ReaderContentViewDelegate methods
- (void)contentView:(ReaderContentView *)contentView touchesBegan:(NSSet *)touches
{
if ((mainToolbar.hidden == NO) || (mainPagebar.hidden == NO))
{
if (touches.count == 1) // Single touches only
{
UITouch *touch = [touches anyObject]; // Touch info
CGPoint point = [touch locationInView:self.view]; // Touch location
CGRect areaRect = CGRectInset(self.view.bounds, TAP_AREA_SIZE, TAP_AREA_SIZE);
if (CGRectContainsPoint(areaRect, point) == false) return;
}
[mainToolbar hideToolbar]; [mainPagebar hidePagebar]; // Hide
lastHideTime = [NSDate date];
}
}
#pragma mark ReaderMainToolbarDelegate methods
- (void)tappedInToolbar:(ReaderMainToolbar *)toolbar doneButton:(UIButton *)button
{
#if (READER_STANDALONE == FALSE) // Option
[document saveReaderDocument]; // Save any ReaderDocument object changes
[[ReaderThumbQueue sharedInstance] cancelOperationsWithGUID:document.guid];
[[ReaderThumbCache sharedInstance] removeAllObjects]; // Empty the thumb cache
if (printInteraction != nil) [printInteraction dismissAnimated:NO]; // Dismiss
if ([delegate respondsToSelector:#selector(dismissReaderViewController:)] == YES)
{
[delegate dismissReaderViewController:self]; // Dismiss the ReaderViewController
}
else // We have a "Delegate must respond to -dismissReaderViewController: error"
{
NSAssert(NO, #"Delegate must respond to -dismissReaderViewController:");
}
#endif // end of READER_STANDALONE Option
}

How to add a CCsprite to layer from array

Hi guys I really need some help, I have been stuck in this part of my game for over a week now and I can't seem to get past this issue, So have look at my code below,
#import "HelloWorldLayer.h"
#import "AppDelegate.h"
#implementation HelloWorldLayer
+(CCScene *) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
// 'layer' is an autorelease object.
HelloWorldLayer *layer = [HelloWorldLayer node];
// add layer as a child to scene
[scene addChild: layer];
// return the scene
return scene;
}
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super's" return value
if( (self=[super init]) ) {
moles = [[NSMutableArray alloc] init];
winSize = [[CCDirector sharedDirector]winSize];
CCSprite *mole1 = [CCSprite spriteWithFile:#"lightsabericonblue.png"];
[self starCreateCurrentLevel:mole1];
}
return self;
}
-(void)starCreateCurrentLevel:(CCSprite *)mole1{
starCountCurrentLevel = 10;
for (int i = 0; i < starCountCurrentLevel;) {
[moles addObject:mole1];
starCountCurrentLevel--;
}
[self schedule:#selector(tryPopMoles:) interval:1];
}
- (void)tryPopMoles:(ccTime)dt {
if(moles.count != 0){
for (CCSprite *mole in moles) {
if (arc4random() % moles.count == 0) {
if (mole.numberOfRunningActions == 0) {
[self popMole:mole];
}
}
}
}else if(moles.count == 0){
NSLog(#"No More Moles To Spawn");
[self unschedule:#selector(tryPopMoles:)];
}
}
- (void) popMole:(CCSprite *)mole {
mole.position = ccp(150, 150);
[self addChild:mole];
}
- (void) dealloc
{
[moles release];
moles = nil;
[super dealloc];
}
#end
When I run this code i get the following error, * Assertion failure in -[HelloWorldLayer addChild:z:tag:], /Users/....../libs/cocos2d/CCNode.m:335.
I when i add the child in the init method its fine but I don't want to do that, I want to be able to call the try pop mole which will then call the pop mole based on if there is anymore sprites left in the array, I have a feeling I am missing something or doing something wrong.
UPDATE -
#import "HelloWorldLayer.h"
#import "AppDelegate.h"
#pragma mark - HelloWorldLayer
CGSize winSize;
int enemyX;
int enemyY;
int randomAngleY;
int randomAngleX;
int winSizeX;
int winSizeY;
int minDuration = 1;
int maxDuration = 4.0;
int rangeDuration;
int actualDuration;
int starCountCurrentLevel;
int test = 0;
#implementation HelloWorldLayer
+(CCScene *) scene
{
CCScene *scene = [CCScene node];
HelloWorldLayer *layer = [HelloWorldLayer node];
[scene addChild: layer];
return scene;
}
-(id) init
{
if( (self=[super init]) ) {
moles = [[NSMutableArray alloc] init];
winSize = [[CCDirector sharedDirector]winSize];
[self starCreateCurrentLevel];
}
return self;
}
-(void)starCreateCurrentLevel{
starCountCurrentLevel = 10;
for (int i = 0; i < starCountCurrentLevel;) {
[moles addObject:[CCSprite spriteWithFile:#"lightsabericonblue.png"]];
starCountCurrentLevel--;
}
[self schedule:#selector(tryPopMoles:) interval:3];
}
- (void)tryPopMoles:(ccTime)dt {
NSMutableArray *tempArray = [NSMutableArray arrayWithArray:moles];
for (int randomIndex = tempArray.count -1; randomIndex < tempArray.count; randomIndex--) {
CCSprite * sprite = (CCSprite *)[tempArray objectAtIndex:randomIndex];
//CCSprite *sprite = [tempArray objectAtIndex:randomIndex];
[self popMole:sprite];
NSLog(#"Enemy Added");
[tempArray removeObject:sprite];
}
if([tempArray count] == 0){
NSLog(#"No More Moles To Spawn");
[self unschedule:#selector(tryPopMoles:)];
}
}
- (void) popMole:(CCSprite *)sprite {
winSizeX = winSize.width - sprite.contentSize.width + 25;
winSizeY = winSize.height - 25 - sprite.contentSize.height + 17;
randomAngleX = arc4random() % winSizeX;
randomAngleY = arc4random() % winSizeY;
enemyX = arc4random() % winSizeX ;
enemyY = arc4random() % winSizeY;
rangeDuration = maxDuration - minDuration;
actualDuration = (arc4random() % rangeDuration) + minDuration;
sprite.position = ccp(enemyX, enemyY);
[self addChild:sprite];
}
- (void) dealloc
{
[moles release];
moles = nil;
[super dealloc];
}
#end
You're only creating the sprite once, but trying to add it several times. (Remember, these are pointers to objects, so you're always referring to exactly the same sprite.) If you want 10 versions of the same sprite (at different positions, scales, speeds, whatever), you'll need to create the sprite (via the creator method) 10 times. You can do a copy on the original one, or just create it on the fly:
-(void)starCreateCurrentLevel:(CCSprite *)mole1{
starCountCurrentLevel = 10;
for (int i = 0; i < starCountCurrentLevel;) {
//[moles addObject:mole1];
// ^^ You're adding the same sprite (meaning same pointer reference) again and again. Try this instead:
[moles addObject:[CCSprite spriteWithFile:#"lightsabericonblue.png"]];
starCountCurrentLevel--;
}
Of course, now you don't need to pass mole1 into your method. You may (depending on your need) consider passing in a spriteFrameName or something.

Strange "splitting" with custom UICollectionViewLayout upon resizing

I have a custom UICollectionViewLayout class that is exhibiting a weird problem. Screen shots above demonstrate. As the keyboard would obscure the lower fields is they were edited, I wanted to shorten the UICollectionView so that it would not be obscured by the keyboard when it came up. The problem is that I get the result in the right picture. The orange border is the background of the view hosting the UICollectionView, the red is the background color of the UICollectionView. The view with the orange background is the root view for the view controller and is resized with the following (self being the view controller).
CGRect frame = self.view.frame;
frame.size.height -= 300;
self.view.frame = frame;
It indicates that the view gets sized as desired, but for some reason the UICollectionView thinks it does not need to draw the cells in the lower portion. The place where it splits seem to be about consistent but arbitrary. If the original view is scrolled down it does not necessarily split at the section header.
In the layout class, if I return YES for - (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds it draws properly but does full redraw so it looks like hell as it does that shifting/fadey thing. And resizing the view does not really invalidate the layout, there is no reason the same layout cannot be used.
Looking for any ideas as to what might be going on. The layout code follows:
//
// MyLayout.h
// uicontroller
//
// Created by Guy Umbright on 8/1/12.
// Copyright (c) 2012 Guy Umbright. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "SFNativeLayout.h"
#import "SFLayoutView.h"
#class SFLayout;
#interface SFLayout : UICollectionViewLayout
#property (readonly, strong) SFNativeLayout* sfLayout;
#property (assign) BOOL deferRowsColsToCollectionView;
#property (strong) SFLayoutView* layoutView;
- (id) initWithDictionary:(NSDictionary*) dict;
- (NSInteger) numberOfSections;
- (NSInteger) numberOfItemsInSection:(NSInteger)section;
#end
//
// MyLayout.m
// uicontroller
//
// Created by Guy Umbright on 8/1/12.
// Copyright (c) 2012 Guy Umbright. All rights reserved.
//
#import "SFLayout.h"
#define ROW_HEIGHT 81 //79 with one pixel top bottom
#define HEADER_HEIGHT 30
#interface SFLayout ()
#property (strong) SFNativeLayout* sfLayout;
#property (nonatomic, strong) NSMutableArray* sectionMetrics;
#end
#implementation SFLayout
///////////////////////////////////////////////////////////////
//
///////////////////////////////////////////////////////////////
- (id) initWithDictionary:(NSDictionary*) dict
{
if (self = [super init])
{
self.sfLayout = [[SFNativeLayout alloc] initWithDictionary:dict];
}
return self;
}
///////////////////////////////////////////////////////////////
//
///////////////////////////////////////////////////////////////
- (NSInteger) numberOfSections
{
if (self.deferRowsColsToCollectionView)
{
return [self.layoutView numberOfSections];
}
else
{
return self.sfLayout.sectionCount;
}
}
///////////////////////////////////////////////////////////////
//
///////////////////////////////////////////////////////////////
- (BOOL) sectionHasHeader:(NSInteger) section
{
BOOL result = YES;
if (self.deferRowsColsToCollectionView)
{
result = [self.layoutView sectionHasHeader:section];
}
return result;
}
///////////////////////////////////////////////////////////////
//
///////////////////////////////////////////////////////////////
- (NSInteger) numberOfColumnsInSection:(NSInteger) section
{
if (self.deferRowsColsToCollectionView)
{
return [self.layoutView numberOfColumnsInSection:section];
}
else
{
SFNativeLayoutSection* layoutSection = [self.sfLayout.sections objectAtIndex:section];
NSInteger sectionColumns = layoutSection.columnCount;
return sectionColumns;
}
}
///////////////////////////////////////////////////////////////
//
///////////////////////////////////////////////////////////////
- (NSInteger) numberOfRowsInSection:(NSInteger) section
{
if (self.deferRowsColsToCollectionView)
{
return [self.layoutView numberOfRowsInSection:section];
}
else
{
SFNativeLayoutSection* layoutSection = [self.sfLayout.sections objectAtIndex:section];
return layoutSection.rowCount;
}
}
///////////////////////////////////////////////////////////////
//
///////////////////////////////////////////////////////////////
- (CGFloat) heightForSection:(NSInteger) sectionNdx
{
CGFloat height = 0;
if (self.deferRowsColsToCollectionView)
{
height = [self numberOfRowsInSection:sectionNdx] * ROW_HEIGHT;
if ([self sectionHasHeader:sectionNdx])
{
height += HEADER_HEIGHT;
}
}
else
{
SFNativeLayoutSection* section = [self.sfLayout.sections objectAtIndex:sectionNdx];
height += section.rowCount * ROW_HEIGHT;
if (section.includeHeader)
{
height += HEADER_HEIGHT;
}
}
return height;
}
///////////////////////////////////////////////////////////////
//
///////////////////////////////////////////////////////////////
- (CGSize)collectionViewContentSize
{
BOOL fillSectionMetrics = NO;
CGFloat lastY = 0;
if (self.sectionMetrics == nil)
{
self.sectionMetrics = [NSMutableArray array];
fillSectionMetrics = YES;
}
CGSize sz = [self collectionView].frame.size;
CGFloat height = 0;
for (NSInteger ndx=0; ndx < [self numberOfSections]; ++ndx)
{
CGFloat sectionHeight = [self heightForSection:ndx];
height += sectionHeight;
if (fillSectionMetrics)
{
[self.sectionMetrics addObject:#{#"height":#(sectionHeight),#"startingY":#(lastY),#"endingY":#(lastY+sectionHeight)}];
lastY += sectionHeight;
}
}
sz.height = height;
return sz;
}
///////////////////////////////////////////////////////////////
//
///////////////////////////////////////////////////////////////
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds
{
return [super shouldInvalidateLayoutForBoundsChange:newBounds];
}
///////////////////////////////////////////////////////////////
//
///////////////////////////////////////////////////////////////
- (NSArray*) attributesForSection:(NSInteger) sectionNdx inRect:(CGRect) rect
{
// NSLog(#"generate attrs for section %d", sectionNdx);
NSMutableArray* result = [NSMutableArray array];
CGRect intersect;
NSDictionary* sectionMetrics = [self.sectionMetrics objectAtIndex:sectionNdx];
SFNativeLayoutSection* layoutSection = [self.sfLayout.sections objectAtIndex:sectionNdx];
NSInteger columnCount = [self numberOfColumnsInSection:sectionNdx];
CGFloat rowStart = [[sectionMetrics valueForKey:#"startingY"] floatValue];
if ((self.layoutView.layoutDatasource != nil) || (layoutSection.includeHeader))
{
CGRect headerFrame = [self collectionView].bounds;
headerFrame.origin.y = rowStart;
headerFrame.size.height = HEADER_HEIGHT;
intersect = CGRectIntersection(rect, headerFrame);
if (!CGRectIsEmpty(intersect))
{
UICollectionViewLayoutAttributes* attr = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:#"Header"
withIndexPath:[NSIndexPath indexPathForItem:0 inSection:sectionNdx]];
attr.frame = headerFrame;
[result addObject:attr];
}
rowStart = headerFrame.origin.y + headerFrame.size.height;
}
for (int rowNdx = 0; rowNdx < [self numberOfRowsInSection:sectionNdx]; rowNdx++)
{
CGRect rowRect = [self collectionView].frame;
rowRect.size.height = ROW_HEIGHT;
rowRect.origin.y = rowStart + (rowNdx * ROW_HEIGHT);
intersect = CGRectIntersection(rect, rowRect);
if (!CGRectIsEmpty(intersect))
{
NSInteger columns = [self numberOfColumnsInSection:sectionNdx];
for (NSInteger colNdx =0; colNdx < columns; ++colNdx)
{
NSIndexPath* indexPath = [NSIndexPath indexPathForItem:rowNdx * columnCount+colNdx inSection:sectionNdx];
CGRect frame;
frame.origin.y = rowRect.origin.y;
frame.size.height = ROW_HEIGHT;
frame.size.width = self.collectionView.frame.size.width/columnCount;
frame.origin.x = colNdx * frame.size.width;
UICollectionViewLayoutAttributes* attrs = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
attrs.frame = frame;
[result addObject:attrs];
}
}
}
return result;
}
///////////////////////////////////////////////////////////////
//
///////////////////////////////////////////////////////////////
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect
{
NSMutableArray* attributes = [NSMutableArray array];
for (NSDictionary* sectionMetric in self.sectionMetrics)
{
//can short circuit based on top of section and bottom of rect
CGRect sectionRect = [self collectionView].frame;
sectionRect.origin.y = [[sectionMetric valueForKey:#"startingY"] floatValue];
sectionRect.size.height = [[sectionMetric valueForKey:#"height"] floatValue];
CGRect intersect = CGRectIntersection(rect, sectionRect);
if (!CGRectIsEmpty(intersect))
{
NSArray* sectionAttrs = [self attributesForSection:[self.sectionMetrics indexOfObject:sectionMetric] inRect:intersect];
[attributes addObjectsFromArray:sectionAttrs];
}
}
return attributes;
}
///////////////////////////////////////////////////////////////
//
///////////////////////////////////////////////////////////////
- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath
{
return [super layoutAttributesForItemAtIndexPath:indexPath];
}
///////////////////////////////////////////////////////////////
//
///////////////////////////////////////////////////////////////
- (NSInteger)numberOfItemsInSection:(NSInteger)section
{
SFNativeLayoutSection* layoutSection = [self.sfLayout.sections objectAtIndex:section];
NSInteger sectionColumns = [self numberOfColumnsInSection:section];
NSInteger sectionRows = layoutSection.rowCount; //%%%
return sectionColumns * sectionRows;
}
#end

NSSound not working properly

I am using Cocoa on Mac 10.6. I am trying to have a metronome click out the time but when I run the code only the first two sounds are played then it is quiet till the end when a sound plays again. If I replace the [player play] statements with NSBeep() it works fine. Any suggestions?
#import <Cocoa/Cocoa.h>
#interface Metronome : NSObject {
NSInteger timeSig;
NSInteger noteValue;
NSInteger bpm;
NSUInteger beatNumber;
CGFloat duration;
NSSound *tickPlayer;
NSSound *tockPlayer;
}
#property(readwrite) NSInteger timeSig;
#property(readwrite) NSInteger noteValue;
#property(readwrite) NSInteger bpm;
#property(readwrite) float duration;
#property(readwrite) NSUInteger beatNumber;
-(id)init;
-(id)initWithTimeSig:(NSInteger)ts andNoteValue:(NSInteger)nv andBpm:(NSInteger)bp;
-(void)BeginMetronome;
-(void)PlaySound;
#end
#import "Metronome.h"
#define defaultBpm 80
#define defaultTimeSig 4
#define defaultNoteValue 4
#implementation Metronome
#synthesize timeSig, noteValue, duration, bpm, beatNumber;
-(id)init{
return [self initWithTimeSig:defaultTimeSig andNoteValue:defaultNoteValue andBpm:defaultBpm];
}
-(id)initWithTimeSig:(NSInteger)ts andNoteValue:(NSInteger)nv andBpm:(NSInteger)bp {
[super init];
if(self){
self.timeSig = ts;
self.noteValue = nv;
self.bpm = bp;
self.duration = 60.0/bpm;
tickPlayer = [NSSound soundNamed:#"Hat1"];
tockPlayer = [NSSound soundNamed:#"Hat2"];
self.beatNumber = 1;
}
return self;
}
-(void)BeginMetronome{
BOOL continuePlaying = YES;
NSInteger iter=0;
while (continuePlaying){
if(iter > 12){
continuePlaying = FALSE;
}
iter++;
[self PlaySound];
NSDate *curtainTime = [[NSDate alloc] initWithTimeIntervalSinceNow:self.duration];
NSDate *currentTime = [[NSDate alloc] init];
while (continuePlaying && ([currentTime compare:curtainTime] != NSOrderedDescending)) {
// if ([soundPlayerThread isCancelled] == YES) {
// continuePlaying = NO;
//}
//[NSThread sleepForTimeInterval:0.01];
sleep(.01);
//[tickPlayer stop];
//[tockPlayer stop];
[currentTime release];
currentTime = [[NSDate alloc] init];
}
[curtainTime release];
[currentTime release];
}
}
- (void)PlaySound { //***********Problem in this loop
if ([tickPlayer isPlaying])
[tickPlayer stop];
if ([tockPlayer isPlaying])
[tockPlayer stop];
if (beatNumber == 1) {
[tockPlayer play];
}
else if (beatNumber == 2){
[tickPlayer play];
}
else if (beatNumber == self.timeSig) {
beatNumber = 0;
[tickPlayer play];
}
else{
//[tickPlayer stop];
[tickPlayer play];
NSBeep();
}
beatNumber++;
//NSLog(#" %d ", beatNumber);
// NSBeep();
}
#end
I believe your use of sleep() is blocking the playing of NSSound. That's a very sloppy way to do this, instead use a timer like so:
static NSInteger iter;
- (void) beginMetronome {
iter = 0;
NSTimer *timer = [NSTimer timerWithTimeInterval:self.duration target:self selector:#selector(continueMetronome:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
[timer fire];
}
- (void) continueMetronome:(NSTimer *)theTimer {
[self PlaySound];
if (++iter > 12) {
[theTimer invalidate];
}
}
Also, you must retain the sounds that you plan to use in your init method.
tickPlayer = [[NSSound soundNamed:#"Hat1"] retain];
tockPlayer = [[NSSound soundNamed:#"Hat2"] retain];
And Cocoa methods should start with a lowercase letter like I've written them. I'm not too sure how metronomes are supposed to work, so you may have to change the value of 12 to something else.