Xcode display random images instead of text from NSArray - uiimageview

Hoping someone can help me make the following NSArray of text be an array of images that can randomize the random images instead of the current text. Any help is greatly appreciated.
#synthesize predictions = _predictions;
- (NSArray *) predictions {
if (_predictions == nil){
_predictions = [[NSArrayalloc] initWithObjects:
#"Today",
#"Tomorrow",
#"Some other time", nil];
}
return_predictions;
}
- (NSString*) randomPrediction {
int random = arc4random_uniform(self.predictions.count);
return [self.predictions objectAtIndex:random];
}

#synthesize predictions = _predictions;
- (NSArray *) predictions {
if (_predictions == nil){
_predictions = [[NSArray alloc] initWithObjects:
#"today.png",
#"tomorrow.png",
#"someothertime.png", nil];
}
return_predictions;
}
- (NSString*) randomPrediction {
int random = arc4random_uniform(self.predictions.count);
return [self.predictions objectAtIndex:random];
}
And use of this....
UIImage myimage=[UIImage imageNamed:[self randomPrediction]];
That's it..I hope this answer will be helpful for you.Enjoy
Thanks,

Related

PHImagemanager requestImageForAsset memory issue

I want to use PHImagemanager to get all photos on the device.
If I set the targetsize too high the app will crash because of memory warnings. So I tested the request without any use of the returned images and set each image to nil, but still app is crashing. I don't know what I'm doing wrong. Can someone help please?
requestOptions = [[PHImageRequestOptions alloc] init];
requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
requestOptions.synchronous = false;
assetsOfPhotos = [PHAsset fetchAssetsWithMediaType: PHAssetMediaTypeImage options: nil];
PHImageManager *manager = [PHImageManager defaultManager];
#autoreleasepool {
for (int i = 0; i <= totalImages - 1; i++) {
PHAsset *asset = assetsOfPhotos[i];
[manager requestImageForAsset: asset
targetSize: CGSizeMake(640, 480)
contentMode: PHImageContentModeDefault
options: requestOptions
resultHandler: ^void(UIImage *image, NSDictionary *info) {
image = nil;
}];
}
}
Setting size to 640x480 crash after about 200 images, 320x240 after about 800 images. As a 640x480 image needs 4 times memory then 320x240 image it seems that the app crashes after the same amount of memory that was allocated. So for me this means that I cannot show more images than 200 imags with 640x480 on the test device, because I cannot free allocated memory.
In order to make your #autoreleasepool work you need to set requestOptions.synchronous to YES, and use your own async queue if you want to make the request operation asynchronously.
Please use #autoreleasepool inside the for loop.
for (int i = 0; i <= totalImages - 1; i++) {
#autoreleasepool {
//Your code
}
}
If you want load all photos that you have in Photos.app and you didn't want iCloud. You can do:
That example works with a collection view.
#interface GalleryViewModel ()
#property (strong, nonatomic) NSMutableArray<PHAsset *> *assets;
#property (strong, nonatomic) PHImageManager *imageManager;
#property (strong, nonatomic) PHImageRequestOptions *requestOptions;
#property (strong, nonatomic) NSMutableArray<UIImage *> *imagesList;
#end
#implementation GalleryViewModel
- (instancetype) initWithContext:(ITXAppContext *)context {
self = [super initWithContext:context];
if (self) {
_assets = [[NSMutableArray alloc] init];
_imageManager = [PHImageManager defaultManager];
_requestOptions = [[PHImageRequestOptions alloc] init];
_imagesList = [[NSMutableArray alloc] init];
}
return self;
}
#pragma mark - Public methods
// ==================================================================================
// Public methods
- (void) viewModelDidLoad {
[self obtainAllPhotos];
}
#pragma mark - Private methods
// ==================================================================================
// Private methods
- (void) obtainAllPhotos {
self.requestOptions.resizeMode = PHImageRequestOptionsResizeModeExact;
self.requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
self.requestOptions.synchronous = YES;
self.requestOptions.networkAccessAllowed = NO;
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"creationDate" ascending:NO]];
PHFetchResult<PHAsset *> *result = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:fetchOptions];
__weak GalleryViewModel *weakSelf = self;
[result enumerateObjectsUsingBlock:^(PHAsset * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
[weakSelf.assets addObject:obj];
if (idx >= ([result count] - 1)) {
[weakSelf.viewDelegate setupView];
}
}];
}
#pragma mark - Get data from object
// ==================================================================================
// Get data from object
- (NSInteger) sizeGallery {
if (self.assets) {
return [self.assets count];
}
return 0;
}
- (UIImage *) imagesFromList:(NSInteger) index {
__block UIImage *imageBlock;
[self.imageManager requestImageForAsset:[self.assets objectAtIndex:index] targetSize:CGSizeMake(200, 200) contentMode:PHImageContentModeAspectFit options:self.requestOptions resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
if (result) {
imageBlock = result;
}
}];
return imageBlock;
}
#end

MapView Problems - Pin change color when map reloded

I have a problem with the PIn color mapView when a refresh is done.
In my I app i display some point with two color in order to identify if a service is available.
On the first start, no problems appear. The code is the follower:
- (void)viewDidLoad
{
[super viewDidLoad];
[self dowloadPoint]; // here I exucte the first start
}
- (void)dowloadPoint{
NSURL *url1 =[NSURL URLWithString:#"http:MYUSRL"];
NSData *datos1 =[[NSData alloc] initWithContentsOfURL:url1];
[self plotBarPosition:datos_string1]; //Here I call the plotBarPosition method
}
- (void)plotBarPosition:(NSString *)datos_string1 {
for (id<MKAnnotation> annotation in _mapView.annotations) {
[_mapView removeAnnotation:annotation];
}
// Parse the string into JSON
NSDictionary *json = [(NSDictionary*)[datos_string1 JSONValue]objectForKey:#"features"];
// Get the objects you want, e.g. output the second item's client id
NSArray *items_properties = [json valueForKeyPath:#"properties"];
NSArray *items_geo = [json valueForKeyPath:#"geometry"];
for (int i = 0; i < [json count]; i++){
NSString *nomprePunto =[[items_properties objectAtIndex:i] objectForKey:#"title"];
NSNumber *lat =[[[items_geo objectAtIndex:i] objectForKey:#"coordinates"] objectAtIndex:0];
NSNumber *lon =[[[items_geo objectAtIndex:i] objectForKey:#"coordinates"] objectAtIndex:1];
CLLocationCoordinate2D coordinate;
coordinate.latitude = lat.doubleValue;
coordinate.longitude = lon.doubleValue;
//ESTADO
NSString *description = [[items_properties objectAtIndex:i] objectForKey:#"description"];
NSString *estado_punto = [[NSString alloc]init];
if ([description rangeOfString:#"Averiado"].location == NSNotFound) {
estado_punto = #"Available";
} else {
estado_punto = #"NOt Available";
averiados ++;
}
NSString *averiadosStr = [NSString stringWithFormat:#"%d",averiados];
averiadosLabel.text = averiadosStr;
MyLocation *location =[[MyLocation alloc] initWithName:nomprePunto coordinate:coordinate estado:estado_punto];
[_mapView addAnnotation:location];
}
}
- (MKPinAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(MyLocation *)annotation {
static NSString *identifier = #"MyLocation";
if ([annotation isKindOfClass:[MyLocation class]]) {
MKPinAnnotationView *annotationView = (MKPinAnnotationView *) [_mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil) {
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
if([[annotation estado] isEqualToString:#"En Servicio"])
annotationView.pinColor = MKPinAnnotationColorGreen;
} else {
annotationView.annotation = annotation;
}
return annotationView;
}
return nil;
}
But whe I add a refres button that is function is simply a refreshcalling the dowloadPoint once again,
- (IBAction)refresh{
[self dowloadPoint];
}
the color of pins change in a "random manner", not corrisponding with the real state of point.
Any ideas about what is happening? Thanks in advance.
EDIT: It seemps pproblems is due to:
for (id<MKAnnotation> annotation in _mapView.annotations) {
[_mapView removeAnnotation:annotation];
}
erasing it, the app work properly but pins area drown abow the previous ones...:S
The default color of the pin is red. You set it to green if the estado property of your MyLocation object is equal to #"En Servicio". I understand that sometimes the color is red, when your estado property is equal to #"En Servicio", or sometimes green when it is not.
One reason could be that your MyLocation object simply does no longer exist when you press the refresh button. In this case, you might still have a pointer to the memory location where it once existed, but this location may have been overwritten by anything, causing a random color.
This can happen e.g. if your MyLocation object has been created as an autorelease object that has been released when you returned to the main event loop, i.e. to handle user interactions.
This should not be the case if you are using ARC.

How to increment a 'score' during fast enumeration

I have the following code which I would like to use to check user answers and output a score (out of 5). I use a plist with the answers in and check the textField.text against it. What I'm struggling with is: how to get an output score as a total using this method?
- (IBAction)checkAnswers:(UITextField *)textField
{
NSString *path2 = [[NSBundle mainBundle] pathForResource:#"7A Cells Microscopes 3" ofType:#"plist"];
NSDictionary *dictionary = [[NSDictionary alloc] initWithContentsOfFile:path2];
NSString *tester = [NSString stringWithFormat:#"%i", textField.tag];
// NSDictionary *secondDict = [dictionary valueForKey:tester];
// NSString *answer = [secondDict valueForKey:#"Answer"];
// if ([textField.text isEqualToString:[[dictionary valueForKey:tester] valueForKey:#"Answer"]]) {
// NSLog(#"YAY");
// }
NSArray *allTextFields = [[NSArray alloc] initWithObjects:eyepiece, objectiveLens, focussingKnobs, stage, mirror, nil];
for (textField in allTextFields) {
int x = 0;
if ([textField.text isEqualToString:[[dictionary valueForKey:tester] valueForKey:#"Answer"]]) {
x++;
NSLog(#"%i", x);
}
}
Any help would be much appreciated!
Many thanks.
Assuming the rest of your code is good, just move int x = 0; outside the for loop. The way you have it coded x is reset to 0 on every loop... so it never counts.

NSMutableArray of Classes in XCode

I'm working on an iPhone app and I have defined a class as so:
#interface PlotData : NSObject {
NSString *sProbeID;
NSMutableArray *dataPoints;
}
#property (nonatomic, retain) NSString *sProbeID;
#property (nonatomic, retain) NSMutableArray *dataPoints;
#end
#implementation PlotData
#synthesize sProbeID;
#synthesize dataPoints;
- (void)dealloc {
[sProbeID release];
[dataPoints release];
[super dealloc];
}
#end
In my main code, I need to create a NSMutableArray of this class. I've got the NSMutableArray defined in the main code (called AllTheProbes) and then this code attempts to find the sProbeID and if it doesn't find it, it adds a new PlotData class to the array.
-(void) AddDataPointDictionary:(NSDictionary *)aDict WithProbe:(ProbeObj *)aProbe{
NSLog(#"In AddDataPointDictionary.");
//The first step is to find the probe.
int nProbeLoc = -1;
PlotData *aPlotDataObj;
for (int i=0; i < [self.AllTheProbes count]; i++) {
aPlotDataObj = [self.AllTheProbes objectAtIndex:i];
if (aPlotDataObj.sProbeID == aProbe.sID) {
nProbeLoc = i;
}
}
if (nProbeLoc == -1) {
NSLog(#" Did not find the record for %#.", aProbe.sID);
//We need to add this probe to the array of all probes.
PlotData *newPlot = [[PlotData alloc]init];
newPlot.sProbeID = aProbe.sID;
NSMutableArray *newArr = [[NSMutableArray alloc]initWithCapacity:0];
newPlot.dataPoints = newArr;
[self.AllTheProbes addObject:newPlot];
[newPlot release];
[newArr release];
//set aPlotDataObj equal to the object we just added.
for (int i=0; i < [self.AllTheProbes count]; i++) {
aPlotDataObj = [self.AllTheProbes objectAtIndex:i];
if (aPlotDataObj.sProbeID == aProbe.sID) {
nProbeLoc = i;
}
}
NSLog(#" Found the added record at %d.", nProbeLoc);
aPlotDataObj = [self.AllTheProbes objectAtIndex:nProbeLoc];
}
else{
NSLog(#" Found %#.", aPlotDataObj.sProbeID);
//Use the record we found
aPlotDataObj = [self.AllTheProbes objectAtIndex:nProbeLoc];
}
//Add the dictionary to the plot array
[aPlotDataObj.dataPoints addObject:aDict];
NSLog(#" Point added.");
}
The problem I am having is that the data does not appear to get stored. When a probe is not found, after adding the new PlotData to the AllTheProbes array, the program still does not find the record. Here's the output from the NSLogs.
2011-05-21 09:53:24.600 Stoker Monitor[4545:207] In AddDataPointDictionary.
2011-05-21 09:53:24.601 Stoker Monitor[4545:207] Did not find the record for 7200001259348330.
2011-05-21 09:53:24.601 Stoker Monitor[4545:207] Found the added record at -1.
2011-05-21 09:53:24.602 Stoker Monitor[4545:207] Point added.
Notice that the 3rd output line says it found the added record at -1, which means it did not find it after adding it.
Can anyone tell me what I am doing wrong?
Thanks,
NCGrimbo
Have you alloc, inited the array?
Like so:
NSMutableArray *AllTheProbes = [[NSMutableArray alloc] init];
And why are you calling self.AllTheProbes? shouldnt it just be "AllTheProbes"?
Hope that helps.

How do I call this method? (Objective C)

I have this method which will report a score to game center:
- (void)reportScore: (int64_t) forCategory: (NSString*) category
{
GKScore *scoreReporter = [[[GKScore alloc] initWithCategory:category] autorelease];
scoreReporter.value = passedint;
[scoreReporter reportScoreWithCompletionHandler:^(NSError *error) {
if (error != nil)
{
// handle the reporting error
}
}];
}
Now I have an ibaction to try to call that method but I am not able to figure it out..
- (IBAction)uploadscore {
passedint = [[NSUserDefaults standardUserDefaults] integerForKey:#"Scoreoneplayer"];
NSLog(#"%i", passedint);
[self reportScore:(passedint)forCategory :(NSString *) category];
}
passedint is the int I want to upload to Game Center. If anyone can help, that would be greatly appreciated! :)
This should do it:
[self reportScore: passedint forCategory: #"Put your category here"];
You shouldn't need to provide types in the method call.

Resources