CATiledLayer and not rendered slices - ios

The problem:
I've to render a big image 7148x15000px (a custom map), so i've looking around for something usefull and i've found BitmapSlice, but the problem is that the very first time i run the app (on device and simulator) several slices aren't loaded correctly and i see the image with large black holes.
Code:
BitmapSliceViewController.h
#import <UIKit/UIKit.h>
#interface BitmapSliceViewController : UIViewController<UIScrollViewDelegate>
#property (nonatomic, retain) UIImageView *_zoomView;
#property (nonatomic, retain) IBOutlet UIScrollView *scrollView;
- (void)saveTilesOfSize:(CGSize)size forImage:(UIImage*)image toDirectory
(NSString*)directoryPath usingPrefix:(NSString*)prefix;
#end
BitmapSliceViewController.m
#import "BitmapSliceViewController.h"
#import "TileView.h"
#implementation BitmapSliceViewController
#synthesize scrollView;
- (void)dealloc
{
[super dealloc];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (void)viewDidLoad
{
[super viewDidLoad];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *directoryPath = [paths objectAtIndex:0];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage *big = [UIImage imageNamed:#"map.jpg"];
[self saveTilesOfSize:(CGSize){256, 256} forImage:big toDirectory:directoryPath usingPrefix:#"map_"];
dispatch_async(dispatch_get_main_queue(), ^{
[scrollView setNeedsDisplay];
});
});
TileView *tv = [[TileView alloc] initWithFrame:(CGRect){{0,0}, (CGSize){7148,15000}}];
[tv setTileTag:#"map_"];
[tv setTileDirectory:directoryPath];
[scrollView addSubview:tv];
[scrollView setContentSize:(CGSize){7148,15000}];
[scrollView setDelegate:self];
}
- (void)saveTilesOfSize:(CGSize)size
forImage:(UIImage*)image
toDirectory:(NSString*)directoryPath
usingPrefix:(NSString*)prefix
{
CGFloat cols = [image size].width / size.width;
CGFloat rows = [image size].height / size.height;
int fullColumns = floorf(cols);
int fullRows = floorf(rows);
CGFloat remainderWidth = [image size].width - (fullColumns * size.width);
CGFloat remainderHeight = [image size].height - (fullRows * size.height);
if (cols > fullColumns) fullColumns++;
if (rows > fullRows) fullRows++;
CGImageRef fullImage = [image CGImage];
for (int y = 0; y < fullRows; ++y) {
for (int x = 0; x < fullColumns; ++x) {
CGSize tileSize = size;
if (x + 1 == fullColumns && remainderWidth > 0) {
// Last column
tileSize.width = remainderWidth;
}
if (y + 1 == fullRows && remainderHeight > 0) {
// Last row
tileSize.height = remainderHeight;
}
CGImageRef tileImage = CGImageCreateWithImageInRect(fullImage,
(CGRect){{x*size.width, y*size.height},
tileSize});
NSData *imageData = UIImageJPEGRepresentation([UIImage imageWithCGImage:tileImage], 1);
CGImageRelease(tileImage);
NSString *path = [NSString stringWithFormat:#"%#/%#%d_%d.png",
directoryPath, prefix, x, y];
[imageData writeToFile:path atomically:NO];
}
}
}
#end
TileView.h
#interface TileView : UIView
#property (nonatomic, copy) NSString *tileTag;
#property (nonatomic, copy) NSString *tileDirectory;
- (UIImage*)tileAtCol:(int)col row:(int)row;
#end
TileView.m
#import "TileView.h"
#implementation TileView
#synthesize tileTag;
#synthesize tileDirectory;
+ layerClass
{
return [CATiledLayer class];
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (!self) return nil;
return self;
}
- (void)dealloc
{
[super dealloc];
}
- (void)drawRect:(CGRect)rect {
//CGContextRef context = UIGraphicsGetCurrentContext();
CGSize tileSize = (CGSize){256, 256};
int firstCol = floorf(CGRectGetMinX(rect) / tileSize.width);
int lastCol = floorf((CGRectGetMaxX(rect)-1) / tileSize.width);
int firstRow = floorf(CGRectGetMinY(rect) / tileSize.height);
int lastRow = floorf((CGRectGetMaxY(rect)-1) / tileSize.height);
for (int row = firstRow; row <= lastRow; row++) {
for (int col = firstCol; col <= lastCol; col++) {
UIImage *tile = [self tileAtCol:col row:row];
if (tile)
{
CGRect tileRect = CGRectMake(tileSize.width * col, tileSize.height * row, tileSize.width, tileSize.height);
tileRect = CGRectIntersection(self.bounds, tileRect);
[tile drawInRect:tileRect];
// [[UIColor whiteColor] set];
// CGContextSetLineWidth(context, 6.0);
// CGContextStrokeRect(context, tileRect);
}
}
}
}
- (UIImage*)tileAtCol:(int)col row:(int)row
{
NSString *path = [NSString stringWithFormat:#"%#/%#%d_%d.png", tileDirectory, tileTag, col, row];
return [UIImage imageWithContentsOfFile:path];
}
#end
This is the main code of the app, you can download the entire example from the site linked on the top of the post.
As i said the main problem is the rendering of some slices that fail in the first run of the app, other runs seem works correctly.
modifing a bit - (UIImage*)tileAtCol:(int)col row:(int)row
- (UIImage*)tileAtCol:(int)col row:(int)row
{
NSString *path = [NSString stringWithFormat:#"%#/%#%d_%d.png", tileDirectory, tileTag, col, row];
UIImage *img = [UIImage imageWithContentsOfFile:path];
if (img) {
NSLog(#"good");
}
else {
NSLog(#"bad");
}
return img;
}
The problem seems to be here...
Any ideas to fix it?
Thanks in advance

Related

Add GifHud in custom UIView

I am trying to display an Activity Indicator with gif in a small view at top of screen. For this I am using this class (GifHud):
//
// GiFHUD.m
// GiFHUD
//
// Created by Cem Olcay on 30/10/14.
// Copyright (c) 2014 Cem Olcay. All rights reserved.
//
#import "GiFHUD.h"
#import "AppDelegate.h"
#import <ImageIO/ImageIO.h>
#define Size 70
#define FadeDuration 0.3
#define GifSpeed 0.3
#define APPDELEGATE ((AppDelegate*)[[UIApplication sharedApplication] delegate])
#if __has_feature(objc_arc)
#define toCF (__bridge CFTypeRef)
#define fromCF (__bridge id)
#else
#define toCF (CFTypeRef)
#define fromCF (id)
#endif
#pragma mark - UIImage Animated GIF
#implementation UIImage (animatedGIF)
static int delayCentisecondsForImageAtIndex(CGImageSourceRef const source, size_t const i) {
int delayCentiseconds = 1;
CFDictionaryRef const properties = CGImageSourceCopyPropertiesAtIndex(source, i, NULL);
if (properties) {
CFDictionaryRef const gifProperties = CFDictionaryGetValue(properties, kCGImagePropertyGIFDictionary);
if (gifProperties) {
NSNumber *number = fromCF CFDictionaryGetValue(gifProperties, kCGImagePropertyGIFUnclampedDelayTime);
if (number == NULL || [number doubleValue] == 0) {
number = fromCF CFDictionaryGetValue(gifProperties, kCGImagePropertyGIFDelayTime);
}
if ([number doubleValue] > 0) {
// Even though the GIF stores the delay as an integer number of centiseconds, ImageIO “helpfully” converts that to seconds for us.
delayCentiseconds = (int)lrint([number doubleValue] * 100);
}
}
CFRelease(properties);
}
return delayCentiseconds;
}
static void createImagesAndDelays(CGImageSourceRef source, size_t count, CGImageRef imagesOut[count], int delayCentisecondsOut[count]) {
for (size_t i = 0; i < count; ++i) {
imagesOut[i] = CGImageSourceCreateImageAtIndex(source, i, NULL);
delayCentisecondsOut[i] = delayCentisecondsForImageAtIndex(source, i);
}
}
static int sum(size_t const count, int const *const values) {
int theSum = 0;
for (size_t i = 0; i < count; ++i) {
theSum += values[i];
}
return theSum;
}
static int pairGCD(int a, int b) {
if (a < b)
return pairGCD(b, a);
while (true) {
int const r = a % b;
if (r == 0)
return b;
a = b;
b = r;
}
}
static int vectorGCD(size_t const count, int const *const values) {
int gcd = values[0];
for (size_t i = 1; i < count; ++i) {
// Note that after I process the first few elements of the vector, `gcd` will probably be smaller than any remaining element. By passing the smaller value as the second argument to `pairGCD`, I avoid making it swap the arguments.
gcd = pairGCD(values[i], gcd);
}
return gcd;
}
static NSArray *frameArray(size_t const count, CGImageRef const images[count], int const delayCentiseconds[count], int const totalDurationCentiseconds) {
int const gcd = vectorGCD(count, delayCentiseconds);
size_t const frameCount = totalDurationCentiseconds / gcd;
UIImage *frames[frameCount];
for (size_t i = 0, f = 0; i < count; ++i) {
UIImage *const frame = [UIImage imageWithCGImage:images[i]];
for (size_t j = delayCentiseconds[i] / gcd; j > 0; --j) {
frames[f++] = frame;
}
}
return [NSArray arrayWithObjects:frames count:frameCount];
}
static void releaseImages(size_t const count, CGImageRef const images[count]) {
for (size_t i = 0; i < count; ++i) {
CGImageRelease(images[i]);
}
}
static UIImage *animatedImageWithAnimatedGIFImageSource(CGImageSourceRef const source) {
size_t const count = CGImageSourceGetCount(source);
CGImageRef images[count];
int delayCentiseconds[count]; // in centiseconds
createImagesAndDelays(source, count, images, delayCentiseconds);
int const totalDurationCentiseconds = sum(count, delayCentiseconds);
NSArray *const frames = frameArray(count, images, delayCentiseconds, totalDurationCentiseconds);
UIImage *const animation = [UIImage animatedImageWithImages:frames duration:(NSTimeInterval)totalDurationCentiseconds / 100.0];
releaseImages(count, images);
return animation;
}
static UIImage *animatedImageWithAnimatedGIFReleasingImageSource(CGImageSourceRef CF_RELEASES_ARGUMENT source) {
if (source) {
UIImage *const image = animatedImageWithAnimatedGIFImageSource(source);
CFRelease(source);
return image;
} else {
return nil;
}
}
+ (UIImage *)animatedImageWithAnimatedGIFData:(NSData *)data {
return animatedImageWithAnimatedGIFReleasingImageSource(CGImageSourceCreateWithData(toCF data, NULL));
}
+ (UIImage *)animatedImageWithAnimatedGIFURL:(NSURL *)url {
return animatedImageWithAnimatedGIFReleasingImageSource(CGImageSourceCreateWithURL(toCF url, NULL));
}
#end
#pragma mark - GiFHUD Private
#interface GiFHUD ()
+ (instancetype)instance;
#property (nonatomic, strong) UIView *overlayView;
#property (nonatomic, strong) UIImageView *imageView;
#property (nonatomic, assign) BOOL shown;
#end
#pragma mark - GiFHUD Implementation
#implementation GiFHUD
#pragma mark Lifecycle
static GiFHUD *instance;
+ (instancetype)instance {
if (!instance) {
instance = [[GiFHUD alloc] init];
}
return instance;
}
- (instancetype)init {
if ((self = [super initWithFrame:CGRectMake(0, 0, Size, Size)])) {
[self setAlpha:0];
[self setCenter:APPDELEGATE.window.center];
[self setClipsToBounds:NO];
// [self.layer setBackgroundColor:[[UIColor colorWithWhite:0 alpha:0.5] CGColor]];
// [self.layer setCornerRadius:10];
// [self.layer setMasksToBounds:YES];
self.imageView = [[UIImageView alloc] initWithFrame:CGRectInset(self.bounds, 20, 20)];
[self addSubview:self.imageView];
[APPDELEGATE.window addSubview:self];
}
return self;
}
#pragma mark HUD
+ (void)showWithOverlay {
[self dismiss:^{
[APPDELEGATE.window addSubview:[[self instance] overlay]];
[self show];
}];
}
+ (void)show {
[self dismiss:^{
[APPDELEGATE.window bringSubviewToFront:[self instance]];
[[self instance] setShown:YES];
[[self instance] fadeIn];
}];
}
+ (void)dismiss {
if (![[self instance] shown])
return;
[[[self instance] overlay] removeFromSuperview];
[[self instance] fadeOut];
}
+ (void)dismiss:(void(^)(void))complated {
if (![[self instance] shown])
return complated ();
[[self instance] fadeOutComplate:^{
[[[self instance] overlay] removeFromSuperview];
complated ();
}];
}
#pragma mark Effects
- (void)fadeIn {
[self.imageView startAnimating];
[UIView animateWithDuration:FadeDuration animations:^{
[self setAlpha:1];
}];
}
- (void)fadeOut {
[UIView animateWithDuration:FadeDuration animations:^{
[self setAlpha:0];
} completion:^(BOOL finished) {
[self setShown:NO];
[self.imageView stopAnimating];
}];
}
- (void)fadeOutComplate:(void(^)(void))complated {
[UIView animateWithDuration:FadeDuration animations:^{
[self setAlpha:0];
} completion:^(BOOL finished) {
[self setShown:NO];
[self.imageView stopAnimating];
complated ();
}];
}
- (UIView *)overlay {
if (!self.overlayView) {
self.overlayView = [[UIView alloc] initWithFrame:APPDELEGATE.window.frame];
[self.overlayView setBackgroundColor:[UIColor blackColor]];
[self.overlayView setAlpha:0];
[UIView animateWithDuration:FadeDuration animations:^{
[self.overlayView setAlpha:0.3];
}];
}
return self.overlayView;
}
#pragma mark Gif
+ (void)setGifWithImages:(NSArray *)images {
[[[self instance] imageView] setAnimationImages:images];
[[[self instance] imageView] setAnimationDuration:GifSpeed];
}
+ (void)setGifWithImageName:(NSString *)imageName {
[[[self instance] imageView] stopAnimating];
[[[self instance] imageView] setImage:[UIImage animatedImageWithAnimatedGIFURL:[[NSBundle mainBundle] URLForResource:imageName withExtension:nil]]];
}
+ (void)setGifWithURL:(NSURL *)gifUrl {
[[[self instance] imageView] stopAnimating];
[[[self instance] imageView] setImage:[UIImage animatedImageWithAnimatedGIFURL:gifUrl]];
}
#end
In my custom view I am displaying GifHud as follows :
[GiFHUD setGifWithImageName:#"loader-fast-trp48.gif"];
[GiFHUD show];
This however displays the GifHud at centre of screen which I understand. But I want the Hud to appear on the custom view which is at the top of screen. How may I do this? I tried this but it gives exception :
[self addSubview:[GiFHUD self]];
- (instancetype)init {
if ((self = [super initWithFrame:CGRectMake(0, 0, Size, Size)])) {
[self setAlpha:0];
[self setCenter:CGPointMake(self.view.window.center.x, Your_HEIGHT)];
[self setClipsToBounds:NO];
//[self.layer setBackgroundColor:[[UIColor colorWithWhite:0 alpha:0.5] CGColor]];
//[self.layer setCornerRadius:10];
//[self.layer setMasksToBounds:YES];
self.imageView = [[UIImageView alloc] initWithFrame:CGRectInset(self.bounds, 20, 20)];
[self addSubview:self.imageView];
[APPDELEGATE.window addSubview:self];
}
return self;
}
Try resizing the center using [self setCenter:CGPointMake(self.view.window.center.x, Your_HEIGHT)]; in my answer. Hope this help.

How to solve the error (?memory related) on navigating between view controllers

I have two view controllers (CreateReport & ViewReport). and an NSObject class (PDFRenderer).
The infoArray(NSMutableArray)is declared as extern in PDFRenderer(NSObject class) & accessed by import # PDFRenderer.h in CreateReport class. The user selects tableview rows desired and passess the selected items to infoArray(NSMutableArray) and push ViewReport class on navigation stack to view the pdf generated using the items in the array.
CreateReport--(PDFRenderer)-->ViewReport
PROBLEM: After viewing the pdf first time without problem - now I want to navigate back to CreateReport from ViewReport - select or deselect desired table cells - update the infoArray - and push ViewReport class to see the pdf regenerated with items in updated infoArray - I am unable to pass any new changes to the infoArray(NSMutableArray). I am guessing the array is getting released or there is some memory problem. Can some one help me with this?
CreateReport.m
#import "ViewReport.h"
#import "PDFRenderer.h"
-(void)preparePDF{
//self.draftArrray has data for CreateReport tableView cells and gets updated on tableView Cells selection
NSDictionary*id_dict=[self.draftArray objectAtIndex:0];
NSArray* id_arr= [id_dict objectForKey:#"Rows"];
NSMutableArray*id_array=[[NSMutableArray alloc]init];
id_arr= [id_dict objectForKey:#"Rows"];
NSDictionary*dict=[[NSDictionary alloc]init];
for (dict in id_arr) {
NSString*id_string=[dict objectForKey:#"title"];
[id_array addObject:id_string];
}
infoArray=id_array; //pass id_array to infoArray declared in PDFRenderer
}
-(void)IBAction{
[self performSegueWithIdentifier:#"finalViewReport" sender:self];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:#"finalViewReport"]) {
//ViewReport*destViewController = segue.destinationViewController;
[self preparePDF];
}
}
-*-
PDFRenderer.h
#import <Foundation/Foundation.h>
extern NSMutableArray*infoArray;
#interface PDFRenderer : NSObject
#property (nonatomic,strong,retain) NSMutableArray*infoArray;
+ (PDFRenderer *)sharedInstance;
-*-
PDFRenderer.m
#import "PDFRenderer.h"
NSMutableArray*infoArray;
#implementation PDFRenderer
#synthesize infoArray;
+(PDFRenderer*) sharedInstance{
static PDFRenderer* _shared = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_shared = [[self alloc] init];
_shared.infoArray = [[NSMutableArray alloc] init];
});
return _shared;
}
+ (void)drawPageNumber:(NSInteger)pageNum
{
NSString *pageString = [NSString stringWithFormat:#"Page %d", pageNum];
UIFont *theFont = [UIFont systemFontOfSize:12];
CGSize maxSize = CGSizeMake(612, 72);
CGSize pageStringSize = [pageString sizeWithFont:theFont
constrainedToSize:maxSize
lineBreakMode:NSLineBreakByClipping];
CGRect stringRect = CGRectMake(((612.0 - pageStringSize.width) / 2.0),
720.0 + ((72.0 - pageStringSize.height) / 2.0),
pageStringSize.width,
pageStringSize.height);
[pageString drawInRect:stringRect withFont:theFont];
}
+(void)drawPDF:(NSString*)fileName
{
UIGraphicsBeginPDFContextToFile(fileName, CGRectZero, nil);
NSInteger currentPage = 0;
BOOL done = NO;
do {
for ( int i = 0 ; i < 4 ; i++ )
{
// Mark the beginning of a new page.
UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, 612, 792), nil);
// Draw a page number at the bottom of each page.
currentPage++;
[self drawPageNumber:currentPage];
//[self drawText:#"Hello World" inFrame:CGRectMake(0, 0, 300, 50)];
int xOrigin= 50;
int yOrigin= 50;
int rowHeight = 50;
int columnWidth = 512;
int numberOfRows = 7;
int numberOfColumns = 1;
if (!i>0) {
[self drawLabels];
xOrigin= 50;
yOrigin= 300;
CGPoint from = CGPointMake(10, 60);
CGPoint to = CGPointMake(602, 60);
[PDFRenderer drawLineFromPoint:from toPoint:to];
CGPoint from1 = CGPointMake(10, 140);
CGPoint to1 = CGPointMake(602, 140);
[PDFRenderer drawLineFromPoint:from1 toPoint:to1];
}
UIGraphicsEndPDFContext();
}
+(void)drawLabels
{
int i;
NSString*s=[[NSString alloc]init];
int x=20;
int y=47;
for (i=0;i<infoArray.count;i++) {
if (i==0|i==3|i==6|i==9|i==12|i==15) {
x=20;
y+=15;
}
s=[infoArray objectAtIndex:i];
[self drawText:s inFrame:CGRectMake(x, y, 100, 25)];
x+=185;
y+=0;
}
}
-*-
ViewReport.m
-(void)viewDidLoad
{
NSString* fileName = [self getPDFFileName];
[PDFRenderer drawPDF:fileName];
NSURL *url = [NSURL fileURLWithPath:fileName];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[detailview setScalesPageToFit:YES]; //UIWebView*detailview
[detailview loadRequest:request];
//[self.view addSubview:detailview];
}
-(NSString*)getPDFFileName
{
NSString* fileName = #"newReport.PDF";
NSArray *arrayPaths =
NSSearchPathForDirectoriesInDomains(
NSDocumentDirectory,
NSUserDomainMask,
YES);
NSString *path = [arrayPaths objectAtIndex:0];
NSString* pdfFileName = [path stringByAppendingPathComponent:fileName];
return pdfFileName;
}
Remove this line NSMutableArray*infoArray; Since you are using #synthesise you don't need this one.
Also, I don't see where you are using this array after all?

custom UIProgressView class works on 64 bit device but not others

I have a custom UIProgressView class (from John Rommel Estropia) which works perfect on 64 bit iPhone simulator and device. But when I run it on 32bit simulators/devices it did not show on the screen? Any idea?
This problem also valid for another class for drawing circular progress.
Here is .m file:
#import "SPKProgress.h"
#interface SPKProgress()
#property (nonatomic, weak) UIImageView *trackImageView;
#property (nonatomic, weak) UIImageView *progressImageView;
#end
#implementation SPKProgress
#pragma mark - NSObject
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self)
{
[self setupProgressView];
}
return self;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self)
{
[self setupProgressView];
}
return self;
}
#pragma mark - UIView
- (void)layoutSubviews
{
[super layoutSubviews];
UIImageView *trackImageView = self.trackImageView;
UIImageView *progressImageView = self.progressImageView;
if (!trackImageView || !progressImageView)
{
return;
}
CGRect bounds = self.bounds;
CGFloat boundsTop = CGRectGetMinY(bounds);
UIImage *trackImage = self.trackImage;
if (trackImage)
{
CGRect trackFrame = trackImageView.frame;
CGFloat trackHeight = trackImage.size.height;
trackImageView.frame = (CGRect){
.origin.x = CGRectGetMinX(trackFrame),
.origin.y = (boundsTop
+ ((CGRectGetHeight(bounds) - trackHeight) * 0.5f)),
.size.width = CGRectGetWidth(trackFrame),
.size.height = trackHeight
};
}
UIImage *progressImage = self.progressImage;
if (progressImage)
{
CGRect progressFrame = progressImageView.frame;
CGFloat progressHeight = progressImage.size.height;
progressImageView.frame = (CGRect){
.origin.x = CGRectGetMinX(progressFrame),
.origin.y = (boundsTop
+ ((CGRectGetHeight(bounds) - progressHeight) * 0.5f)),
.size.width = CGRectGetWidth(progressFrame),
.size.height = progressHeight
};
}
}
#pragma mark - UIProgressView
- (void)setProgressImage:(UIImage *)progressImage
{
[super setProgressImage:progressImage];
self.progressImageView.image = progressImage;
}
- (void)setTrackImage:(UIImage *)trackImage
{
[super setTrackImage:trackImage];
self.trackImageView.image = trackImage;
}
#pragma mark - private
- (void)setupProgressView
{
if ([self compareVersionString:[UIDevice currentDevice].systemVersion
withVersionString:#"7.1"] == NSOrderedAscending)
{
return;
}
NSArray *subviews = self.subviews;
if ([subviews count] != 2)
{
return;
}
for (UIView *subview in subviews)
{
if (![subview isKindOfClass:[UIImageView class]])
{
return;
}
}
self.trackImageView = subviews[0];
self.progressImageView = subviews[1];
self.trackImageView.image = self.trackImage;
self.progressImageView.image = self.progressImage;
}
- (NSComparisonResult)compareVersionString:(NSString *)versionString1
withVersionString:(NSString *)versionString2
{
NSArray *components1 = [versionString1 componentsSeparatedByString:#"."];
NSArray *components2 = [versionString2 componentsSeparatedByString:#"."];
NSUInteger components1Count = [components1 count];
NSUInteger components2Count = [components2 count];
NSUInteger partCount = MAX(components1Count, components2Count);
for (NSInteger part = 0; part < partCount; ++part)
{
if (part >= components1Count)
{
return NSOrderedAscending;
}
if (part >= components2Count)
{
return NSOrderedDescending;
}
NSString *part1String = components1[part];
NSString *part2String = components2[part];
NSInteger part1 = [part1String integerValue];
NSInteger part2 = [part2String integerValue];
if (part1 > part2)
{
return NSOrderedDescending;
}
if (part1 < part2)
{
return NSOrderedAscending;
}
}
return NSOrderedSame;
}
#end
And the header file:
#import <UIKit/UIKit.h>
#interface SPKProgress : UIProgressView
#end

Objective C why are the objects from my NSMutableArray disappearing?

I'm new to Objective-C and iOS. I'm having trouble with something that is probably easily corrected, but I have no idea why it's happening.
I'll try to give a brief description of what I'm doing and hopefully it'll have enough info to spot the error.
PolygonView.h is a UIView type class, and it declares the NSmutablearray like this:
#property(nonatomic, retain) NSMutableArray *polys;
I init it in PolygonView.m's initWithFrame:(CGRect)Frame method like this:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// Initialization code
}
polys = [[NSMutableArray alloc]init];
[self loadCsv];
return self;
}
inside loadCSV I load a csv use it to create a few poly objects and do some other stuff, but here's the gist of it:
poly* p;
p = [[poly alloc] init];
// here I set a few properties on p from the csv file and then add p to polys like this:
[polys addObject:p];
At the end of the method I use nslog to print the count like this:
NSLog(#"polys size = %i", [polys count]);
This prints "polys size = 100" on the console.
And then I decided to do my own drawRect. and the beginning of it use the same nslog to print the size/count, but "polys size = 0" is printed on the console.
What am I doing wrong? how can I access the objects I added to this array from the drawRect method?
edit:
here's the full polygonView.h file:
#import <UIKit/UIKit.h>
#interface PolygonView : UIView{
NSMutableArray *polys;
}
#property(nonatomic, retain) NSMutableArray *polys;
-(void)loadCSV;
#end
edit 2: the full polygon
//
// PolygonView.m
// Polygon2
//
#import "PolygonView.h"
#import "poly.h"
#implementation PolygonView
#synthesize polys;
-(id)init
{
NSLog(#"regular init");
self = [super init];
if (self) {
self.polys = [[NSMutableArray alloc]init];
[self loadCsv];
}
return self;
}
- (id)initWithFrame:(CGRect)frame
{
NSLog(#"init with frame");
self = [super initWithFrame:frame];
if (self) {
self.polys = [[NSMutableArray alloc]init];
[self loadCsv];
}
return self;
}
-(void)loadCsv
{
poly* p;
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"DivisoesEstaduais" ofType:#"csv"];
NSString *testString = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
NSString *newString = [testString stringByReplacingOccurrencesOfString:#"," withString:#"."];
if (newString) {
NSMutableArray *arrr = [newString componentsSeparatedByString:#"\n"];
for (int i = 0; i < [arrr count]; i++){
if ([[arrr objectAtIndex:i] length] > 0){
p = [[poly alloc] init];
NSMutableArray *arrayatual = [[arrr objectAtIndex:i] componentsSeparatedByString:#";"];
[p setPolyid:[arrayatual objectAtIndex:0]];
[p setPartid:[arrayatual objectAtIndex:1]];
[p setPointid:[arrayatual objectAtIndex:2]];
[p setx:[arrayatual objectAtIndex:3]];
[p sety:[arrayatual objectAtIndex:4]];
[self.polys addObject:p];
NSLog(#"polys size = %i", [self.polys count]); // this increases from 1 to 100
}
}
NSLog(#"polys size = %i", [self.polys count]); // this prints 100
}else{
NSLog(#"not");
}
}
- (void)drawRect:(CGRect)rect{
srandom( time( NULL ) );
CGContextRef context= UIGraphicsGetCurrentContext();
CGContextSetRGBStrokeColor(context, random() % 250, random() % 250, random() % 250, 1.0);
CGContextSetFillColorWithColor(context, [UIColor redColor].CGColor);
CGContextFillPath(context);
int oldtemp = 0;
NSLog(#"drawRect polys pointer = %#", self.polys); // this is null
NSLog(#"polys size = %i", [self.polys count]); // this is zero
for (int i = 0; i < [polys count]; i++){
poly *p = [polys objectAtIndex:i];
int temp = p.getPolyid.intValue;
if (temp == oldtemp){
CGFloat hue = ( arc4random() % 256 / 256.0 ); // 0.0 to 1.0
CGFloat saturation = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0, away from white
CGFloat brightness = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0, away from black
UIColor *color = [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:1];
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillPath(context);
NSLog(#"movetopoint");
CGContextMoveToPoint(context, [p.getx floatValue]+160, [p.gety floatValue]+160);
oldtemp++;
}else{
CGContextAddLineToPoint(context, [p.getx floatValue]+160, [p.gety floatValue]+160);
NSLog(#"addlinetopoint");
}
}
CGFloat hue = ( arc4random() % 256 / 256.0 ); // 0.0 to 1.0
CGFloat saturation = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0, away from white
CGFloat brightness = ( arc4random() % 128 / 256.0 ) + 0.5; // 0.5 to 1.0, away from black
UIColor *color = [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:1];
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextFillPath(context);
}
#end
and here's viewController.m:
//
// ViewController.m
// Polygon2
//
//
#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.view.multipleTouchEnabled = YES;
PolygonView * pv = [[PolygonView alloc] init];
[self.view addSubview:pv];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Edit3:
George Sachin's solution worked: use viewDidAppear instead of viewDidLoad. But why was viewDidLoad causing me trouble? Here's the zipped project in case anyone wants to take a look and try to figure out.
http://www.mediafire.com/download/b9ueqkqbmxswd7a/Polygon2_3.zip
Seems to me ViewDidload is the one I should be using. Should I never use it?
Final Edit:
When you create an initializer for a UIView you should always call super's initWithFrame: or initWithCoder: when you use a .xib
Change your code to this:
-(id)init
{
NSLog(#"regular init");
self = [super initWithFrame:CGRectMake(0, 0, 20, 20)]; // Replace with the dimensions you want
if (self) {
self.polys = [[NSMutableArray alloc]init];
[self loadCsv];
}
NSLog(#"(init)polys size = %i", [self.polys count]);
return self;
}
Try to do this:
1) When you're setting #property(nonatomic, retain) myObj to the object you should do in the .m file #synthesize myObj
2) as HSNN says you should access it via self.myObj
3)It's better to do init part in between this part
if (self) {
// Initialization code
}
phrase "initialization code" was put there not accidentally))
Most likely that root of the problem is forgotten #synthesize but it's better to cover all 3 steps.
good luck. feel free to ask if this won't help)

ios : scrollview not displaying images

I am a beginner and I have developed a program having full screen image scrollview which fetches images from database. but I am getting blank(white) images in output. what will be the reason behind that? plz help, my code is:
#interface GalleryImageScrollViewController ()
{
MyDatabase *data;
NSMutableArray *slideImages;
CGPoint gestureStartPoint,currentPosition;
}
-(void)putImageViewsInScrollView:(int) numberOfImageViews;
#end
#implementation GalleryImageScrollViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.FullScreenImageScroller.delegate= self;
[self putImageViewsInScrollView:slideImages.count];
}
-(void) putImageViewsInScrollView:(int)numberOfImageViews
{
data=[MyDatabase new];
slideImages=[data OpenMyDatabase:#"SELECT pic_name FROM interior" :#"pic_name"];
for(int i=0 ;i< numberOfImageViews; i++)
{
UIImageView *fullScreenImageView = [[UIImageView alloc] init];
fullScreenImageView.frame = CGRectMake((WIDTH_OF_IMAGE * i) , 0, WIDTH_OF_IMAGE, HEIGHT_OF_IMAGE);
fullScreenImageView.image = [UIImage imageNamed:[slideImages objectAtIndex:i]];
[self.FullScreenImageScroller addSubview:fullScreenImageView];
}
[self.FullScreenImageScroller setContentSize:CGSizeMake(WIDTH_OF_SCROLL_PAGE * ([slideImages count]), HEIGHT_OF_IMAGE)];
[self.FullScreenImageScroller setContentOffset:CGPointMake(0, 0)];
[self.FullScreenImageScroller scrollRectToVisible:CGRectMake(WIDTH_OF_IMAGE,0,WIDTH_OF_IMAGE,HEIGHT_OF_IMAGE) animated:NO];
}
Try this
#interface GalleryImageScrollViewController ()
{
MyDatabase *data;
NSMutableArray *slideImages;
CGPoint gestureStartPoint,currentPosition;
}
-(void)putImageViewsInScrollView:(int) numberOfImageViews;
#end
#implementation GalleryImageScrollViewController
- (void)viewDidLoad
{
[super viewDidLoad];
slideImages = [[NSArray alloc]init];
data=[[MyDatabase alloc]init];
slideImages=[data OpenMyDatabase:#"SELECT pic_name FROM exterior" :#"pic_name"];
[self putImageViewsInScrollView:slideImages.count];
self.FullScreenImageScroller.delegate=self;
NSLog(#"Array %#",slideImages);
}
-(void) putImageViewsInScrollView:(int)numberOfImageViews
{
for(int i=0 ;i< numberOfImageViews; i++)
{
UIImageView *fullScreenImageView = [[UIImageView alloc] init];
fullScreenImageView.frame = CGRectMake((WIDTH_OF_IMAGE * i) , 0, WIDTH_OF_IMAGE, HEIGHT_OF_IMAGE);
fullScreenImageView.image = [UIImage imageNamed:[slideImages objectAtIndex:i]];
[self.FullScreenImageScroller addSubview:fullScreenImageView];
}
[self.FullScreenImageScroller setContentSize:CGSizeMake(WIDTH_OF_SCROLL_PAGE * ([slideImages count]), HEIGHT_OF_IMAGE)];
[self.FullScreenImageScroller setContentOffset:CGPointMake(0, 0)];
[self.FullScreenImageScroller scrollRectToVisible:CGRectMake(WIDTH_OF_IMAGE,0,WIDTH_OF_IMAGE,HEIGHT_OF_IMAGE) animated:NO];
}

Resources