Get values from NSMutablearray - ios

I have a NSMutableArray that has three columns with multiple lines with float values, like this:
-0.06, -0.49, -0.76;
-1.05, -0.63, -0.77;
0.73, -0.32, -0.62;
-0.08, -0.61, -1.00;
0.15, -0.42, -0.91;
I used this lines to define the NSMutableArray (anArrayAcel):
NSString *str = [NSString stringWithFormat:#"%#, %#, %#",self.accX.text,self.accY.text, self.accZ.text];
[anArrayAcel addObject:str];
I need access this data to be used in other function. How can I access the values through specific indexes?

It looks like you need an array of arrays. You made an array of NSStrings instead.
Here is one way to do it:
NSMutableArray *row = [
#[
[self.accX.text floatValue]
, [self.accY.text floatValue]
, [self.accZ.text floatValue]
]
mutableCopy
];
[anArrayAcel addObject:row];
The idea is to create an array of NSMutableArrays, presumably in an event handler inside which you add rows to your array. If you do not need the nested arrays to be mutable, skip the mutableCopy part.
Now you can access your data as follows:
float x = anArrayAcel[row][0];
float y = anArrayAcel[row][1];
float z = anArrayAcel[row][2];
Note: if all rows are going to have exactly three values, x, y, and z, you may be better off creating a class to represent three floats instead of using a nested array.

you can design a class named Acel as below:
// Acel.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#interface Acel : NSObject
#property (nonatomic, assign) CGFloat accX;
#property (nonatomic, assign) CGFloat accY;
#property (nonatomic, assign) CGFloat accZ;
- (instancetype)initWithAccX:(CGFloat)accX accY:(CGFloat)accY accZ:(CGFloat)accZ;
#end
and .m is as below:
// Acel.m
#import "Acel.h"
#implementation Acel
- (instancetype)initWithAccX:(CGFloat)accX accY:(CGFloat)accY accZ:(CGFloat)accZ{
self = [super init];
if (self) {
self.accX = accX;
self.accY = accY;
self.accZ = accZ;
}
return self;
}
#end
ViewController as below:
// ViewController.h
#interface ViewController ()
#property (nonatomic, strong) NSMutableArray *acels;
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.acels = [#[] mutableCopy];
Acel *acel0 = [[Acel alloc] initWithAccX:-1.1f accY:0.2f accZ:0.3f];
Acel *acel1 = [[Acel alloc] initWithAccX:-1.1444f accY:0.22f accZ:0.33f];
Acel *acel2 = [[Acel alloc] initWithAccX:-1.1411f accY:0.255f accZ:0.333f];
[_acels addObject:acel0];
[_acels addObject:acel1];
[_acels addObject:acel2];
[self accessAccel1X];
}
- (void)accessAccel1X{
Acel * acel1 = self.acels[1];
NSLog(#"%f", acel1.accX);
}
In my opinion,it is more elegant compared with two-dimensional array.
Because we don't need do like [0][1] and we avoid double circulation if you want to iterate through arrays,

Related

How come the instance of my object is missing the properties I want to assign?

I am trying to create a class in with properties defined in the header. Was planning to populate the object in a for loop. Here is the header, what could I be doing wrong? Am I defining this class wrong?
#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#interface ViewController : UIViewController<UIPickerViewDataSource,
...
#end
#interface PickerObject : NSObject
{
NSString *minutes;
NSNumber *label;
}
#end
In the viewDidLoad I get message saying property minutes not found.
NSMutableArray *arr = [[NSMutableArray alloc] init];
for(int x = 0; x < total; x++)
{
PickerObject *myObject = [[PickerObject alloc] init];
myObject.minutes = x;
myObject.label = #"%# minutes",x;
[_pickerData addObject:myObject];
//[_pickerData addObject:[NSNumber numberWithInt:x]];
[arr addObject:[NSNumber numberWithInt:x]];
}
Here is a screenshot of the error depicting property not found
To access object variables using the dot '.' operator in Objective-C, you need a setter method. The easiest way to achieve this is by defining a property instead, like this:
#interface PickerObject : NSObject
{
}
#property (nonatomic, strong) NSString *minutes;
#property (nonatomic, strong) NSNumber *label;
#end
The object variables, setter- and getter methods you need will be synthesised automatically.

How do i add multiple objects to NSMutableArray and how do i retrieve my objects properties?

Super basic questions, which i'm having problems with.
How do i add multiple objects to my NSMutableArray? (Now i only add one with self.itemsArray[0] = iPhoneItem; )
How do i retrieve for the first objects property (itemName)?
I have a calss: Item - which looks like follows.
Item.h
#interface Item : UITableViewController
#property (nonatomic, copy) NSString *itemTitle;
- (id)initWithItemTitle:(NSString *)aTitle;
#end
Item.m
#interface Item ()
#end
#implementation Item
- (id)initWithTitle:(NSString *)aTitle {
self = [super init];
if (self) {
self.itemTitle = aTitle;
}
return self;
}
#end
And now i just want to create a few objects, add them in to an NSMutableArray and retrieve the itemTitle property.
ViewController.m - (.h has no additional changes from standard "create singel view application"
#import "ViewController.h"
#import "Item.h"
#interface ViewController ()
#property (nonatomic, strong) NSMutableArray *itemsArray;
#end
#implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
Item *iPhoneItem = [[Item alloc] initWithItemTitle:#"iPhone"];
Item *iPadItem = [[Item alloc] initWithItemTitle:#"iPad"];
Item *macBookPro = [[Item alloc] initWithItemTitle:#"MacBookPro"];
self.itemsArray[0] = iPhoneItem;
NSLog(#"%#", self.itemsArray[0].itemTitle); //How would i do this?
}
#end
Best regards, iOS-rookie.
You can simply check iOS reference, no need to ask questions: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSMutableArray_Class/Reference/Reference.html#//apple_ref/occ/instm/NSMutableArray/addObjectsFromArray:
Anyway, here is an example:
[itemsArray addObjectsFromArray: #[obj1, obj2]]; //adding multiple objects
((Item *)[itemsArray firstObject]).itemTitle //get title of your object
It is bad practice to access properties for an object in an array directly like :
self.itemsArray[0].itemTitle
It is cleaner to:
Item iPhoneItem = (Item)[itemsArray objectAtIndex:0];
NSLog(#"%#", iPhoneItem.itemTitle);
Also keep in mind that you can use [itemsArray firstObject]; and [itemsArray lastObject];

UITableView with an array of objects

Im developing an iOs application and i have an array of objects each object has a name, id, amd describtion. i want to display the name in the table view cell and the description in the detailview controller.
I know there are plenty of tutorial it wouldnt work for my case i think.
Where should implement the array in which class the view controller or the class model or the array class model.
May be you can start to hard init your array of objects in your tableViewController viewDidLoad.
#import "TableViewController.h"
#interface TableViewController ()
#property (strong, nonatomic) NSMutableArray *myData;
#end
#implementation TableViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.myData = [[NSMutableArray alloc]init];
YourObectClass *myObject;
for (int i = 0; i < 20; i++) {
myObject = [[YourObectClass alloc] init];
myObject.name = [NSString stringWithFormat:#"Object:%d",i];
[self.myData addObject:myObject];
]
//here you are... now use self.myData as your data source...
}
....
#end

Create array for UITableView headers

In my iPhone app I want to show a table view with section headers.
I have a datasource like this(Example)
(
{date : 12-10-2014 rowdata:abc},
{date : 12-10-2014 rowdata:pqr},
{date : 12-10-2014 rowdata:xyz},
{date : 13-10-2014 rowdata:123},
{date : 13-10-2014 rowdata:780},
{date : 14-10-2014 rowdata:tuv},
)
I want to show the section header as the date - and have to show row data in it like this
(just consider it as a format of table view-dates are it header views and below rows)
12-10-2014
abc
pqr
xyz
13-10-2014
123
780
13-10-2014
tuv
please give me a logic to do how to change or create new arrays with my data source, I am clear working with sectioned tableview and header views.
i can create a seperate array with dates for header view, but how can I show rowdata under every section, because in every section row starts with index 0.
You are basically asking how to categorise your rowdata data by its date key.
Simple. You need to do the following:
Create data models for your data couplets so that its nicer to populate your table with and store in arrays :)
Create a dictionary that will store the date as keys - you can imagine them as categories - and the row data as objects stored in an array for each category.
Step 1:
Create your custom data model to make data management more easier and cleaner.
Create two new files called rowDataModel.h and rowDataModel.m. They will be a subclass of the NSObject class.
This is what your .h file would look like:
#import <Foundation/Foundation.h>
#interface rowDataModel : NSObject
#property (nonatomic, retain) NSString * rowDataDate;
#property (nonatomic, retain) NSString * rowDataInformation;
-(id)initWithJSONData:(NSDictionary*)data;
#end
and in your .m file you will have this:
#import "rowDataModel.h"
#implementation rowDataModel
#synthesize rowDataDate;
#synthesize rowDataInformation;
-(id)initWithJSONData:(NSDictionary*)data{
if (self = [super init]) {
self.rowDataDate = [data objectForKey:#"date"];
self.rowDataInformation = [data objectForKey:#"rowdata"];
}
return self;
}
#end
We are doing this as this will contain easy to work with containers. Its a good way to manage your custom json objects too.
Step 2
Now in your view controller where you will be populating the database and categorising your data, make sure you import your custom rowDataModel.h file
NSMutableDictionary *myData = [[NSMutableDictionary alloc] init];
//Have a for loop that iterates through your array
for(NSDictionary *currentItem in serverArray){
RowData *newItem = [[RowData alloc] initWithJSONData:currentItem];
//If category the date key does not exist, then create a new category for it
if([myData objectForKey:newItem.rowDataDate] == nil){
//We want to create an array for each category that will hold all the row datas
[myDate setObject:[NSMutableArray new] forKey:newItem.rowDataDate];
}
//Grab the array from a particular category and add the current item to this category
[[myDate objectForKey:newItem.rowDataDate] addObject:newItem];
}
Now when you are populating your table delegate methods, in your titleForHeader tableview delegate methods, you simply grab the category titles: the dates from your myData dictionary using the allKeys property, and call the `objectForIndex: method for the section counter in your delegate method, ad you use that string to set the title of your header view by using the titleForHeader table view delegate method.
And in your cellForRowAtIndexPath: delegate method, you simply grab the correct category in your myData array by using the keys, and then access the individual objects in the array based on the row count.
And thats all bro. Goodluck
disclaimer, I have not tested this code, this should work right off the bat :)
The best way to do this would be creating a custom object, let's call it MyDate. My date would have two properties: a date, and an array.
#interface MyDate
#property NSDate *date;
#property NSArray *items;
#end
You parse the string, and for each information bit, you check the date. If the date is not in the array you add it. Then you add the other string to the items array for the appropriate MyDate object.
This way, every object in items starts with index 0, just like the rows in each section. So managing your model this way makes it easy to handle the user interface.
You could do this with arrays and dictionaries but it get's a little messy and you are probably best of creating new objects that can handle this.
I would probably start with something that looks a little like this
#interface NMKSection : NSObject
#property (nonatomic, strong) NSDate *date;
#property (nonatomic, strong) NSArray *rows;
#end
#interface NMKDataSource : NSObject
#property (nonatomic, strong) NSArray *data;
#property (nonatomic, strong) NSArray *sectionSortDescriptors;
#property (nonatomic, strong) NSArray *rowSortDescriptors;
- (NMKSection *)sectionAtIndex:(NSInteger)index;
- (void)processData;
#end
This would then mean that your UITableViewDataSource can look very simple
- (void)methodToSetupDataSource
{
self.dataSource = [[NMKDataSource alloc] init];
self.dataSource.data = data
self.dataSource.sectionSortDescriptors = // optional;
self.dataSource.rowSortDescriptors = // optional;
[self processData];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NMKSection *section = [self.dataSource sectionAtIndex:section];
return [self.dataFormatter stringFromData:section.date];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = // get cell
id row = [self.dataSource sectionAtIndex:indexPath.section].rows[indexPath.row];
// configure cell
return cell;
}
To achieve this all the heavy lifting is hidden in the NMKDataSource. The implementation fo NMKSection can just be left blank as it will contain no logic
#implementation NMKSection
#end
All the hard work is started from processData
#interface NMKDataSource ()
#property (nonatomic, strong) NSArray *sections;
#end
#implementation NMKDataSource
- (id)init;
{
self = [super init];
if (self) {
_sections = [[NSMutableArray alloc] init];
}
return self;
}
- (NMKSection *)sectionAtIndex:(NSInteger)index;
{
return self.sections[index];
}
- (void)processData
{
if (self.sectionSortDescriptors) {
self.sections = [self.unsortedSections sortedArrayUsingDescriptors:self.sectionSortDescriptors];
} else {
self.sections = [self.unsortedSections copy];
}
}
- (NSDictionary *)groupedData;
{
NSMutableDictionary *groupedData = [[NSMutableDictionary alloc] init];
[self.data enumerateObjectsUsingBlock:^(NSDictionary *row, NSUInteger idx, BOOL *stop) {
NSString *key = row[#"date"];
NSMutableArray *rows = groupedData[key];
if (!rows) {
groupedData[key] = rows = [[NSMutableArray alloc] init];
}
[rows addObject:row[#"rowdata"]];
}];
return groupedData;
}
- (NSArray *)unsortedSections;
{
NSMutableArray *unsortedSections = [[NSMutableArray alloc] init];
[self.groupedData enumerateKeysAndObjectsUsingBlock:^(NSDate *date, NSArray *rows, BOOL *stop) {
[unsortedSections addObject:({
NMKSection *section = [[NMKSection alloc] init];
section.date = date;
section.rows = rows;
if (self.rowSortDescriptors) {
section.rows = [rows sortedArrayUsingDescriptors:self.rowSortDescriptors];
}
section;
})];
}];
return [unsortedSections copy];
}
#end
This was written in the browser so it's not been tested. The code it just an example of where I would probably start and develop this further until I was happy

Accessing instance variables from methods

Goal of program: Enter numbers on a viewController. When the user hits Submit button, the data entered by user is passed on to a different class for displaying on a different viewController.
Problem: I am trying to access an instance variable (numberList) in an instance method (-(void)insertNewNumber:(Numbers *)tempNumber), but it never gives me the correct output. But when I access the same variable through a protocol method of UITableViewDataSource, I get the correct answer. I figured this by using NSLog in instance method and protocol method.
Since I have declared numberList as a property variable, I was thought that I can access it from anywhere in the program and get the correct value stored in it. But compiler returned 0 for the NSLog statements when they were called from instance method. When the NSLog statements from protocol method, showed the correct result.
Please help me understand why is this occurring and how can I add elements into an array from any method in a program.
Thank you!
Here's the relevant code I am working on:
Numbers.h:
#interface Numbers:NSObject
#property (strong, retain) NSString *ID;
#property (strong, retain) NSInteger *number;
#end
Numbers.m
#implementation Numbers
#synthesize ID, number;
#end
DisplayNumbers.h
#import <UIKit/UIKit.h>
#import "Numbers.h"
#interface DisplayNumbers : UIViewController <UITableViewDataSource, UITableViewDelegate>
#property (strong, nonatomic) NSMutableArray *numberList;
- (void)insertNewNumber:(Numbers *)tempNumber;
#end
DisplayNumbers.m:
#implementation DisplayNumbers
#synthesize numberList;
- (void)viewDidLoad
{
[super viewDidLoad];
numberList = [[NSMutableArray alloc] init];
Numbers *num0 = [[Numbers alloc] init];
Numbers *num1 = [[Numbers alloc] init];
num0.ID = [NSString stringWithFormat:#"ID 0"];
num0.number = 1111111111;
num1.ID = [NSString stringWithFormat:#"ID 1"];
num0.number = 2222222222;
[numberList addObject:num0];
[numberList addObject:num1];
}
- (void)insertNewNumber:(Numbers *)tempNumber
{
NSLog(#"numberList.count (in -(void)insetNewNumber) = %d", numberList.count);
[numberList addObject:tempNumber];
NSLog(#"numberList.count (in -(void)insetNewNumber) = %d", numberList.count);
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSLog(#"numberList.count (in -(NSInteger)tableView:...) = %d", numberList.count);
Numbers *temp = [[Numbers alloc] init];
temp.ID = #"hi";
temp.Number = 1234;
[numberList addObject:temp];
NSLog(#"numberList.count (in -(NSInteger)tableView:...) = %d", numberList.count);
return numberList.count;
}
#end
Edit 1: Calling of insertNewNumber:.
This method is being called from a different class.
InputNumber.h:
#import <UIKit/UIKit.h>
#import "DisplayNumbers.h"
#interface InputNumber:UIViewController
#property (retain, strong) NSInteger *enteredNumber;
-(void)enteredNumber;
#end
InputNumber.m
#implementation InputNumber
#synthesize enteredNumber;
-(void)enterNumber
{
DisplayNumber *temp = [[DisplayNumber alloc] init];
[temp insertNewNumber:enteredNumber];
}
#end
Since you allocate your numberList in the ViewDidLoad method, be sure to call your insertNewNumber method after the call to ViewDidLoad.
I believe that
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
Numbers *temp = [[Numbers alloc] init];
temp.ID = #"hi";
temp.Number = 1234;
[self insertNewNumber:temp];
return contactList.count;
}
works, right?
If you need to call your insertNewNumber method before the call to ViewDidLoad, allocate your numberList
numberList = [[NSMutableArray alloc] init];
in an overloaded initWithNibName:bundle: method.
Your code doesn't have an ivar called numberList. You need to call the property like this:
self.numberList = [NSMutableArray array];
No need to alloc/init since you're already using a strong reference.
Every time you refer to that numberList object, you need to use self.numberList.
[self.numberList addObject:num0];
[self.numberList addObject:num1];

Resources