Τετάρτη, 7 Νοεμβρίου 2012

add 20 days (or month etc) on one NSDate


NSCalendar*       calendar = [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
NSDateComponents* components = [[NSDateComponents alloc] init];
components.day = 20;
NSDate* newDate = [calendar dateByAddingComponents: components toDate:STARTDATE options: 0];
    [exp setExpireDate:[newDate timeIntervalSinceReferenceDate]];

sort an array of objects with date property of them

finest solution i found was with block


sortedArray = [array sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
        NSDate *first = [(MYOBJECT *)a date] ;
        NSDate *second = [(MYOBJECT *)b date];
        return [first compare:second];
    }];

to reverse ascending to deciding just reverse the first and second

sortedArray = [originalArray sortedArrayUsingComparator:^NSComparisonResult(id a, id b) {
        NSDate *first = [(MYOBJECT *)a date] ;
        NSDate *second = [(MYOBJECT *)b date];
        return [second compare: first];
    }];

Delegate methode - Protocol and how to user a button inside on custom table view cell

Steps:

1. On .h of custom cell  create the protocol. In my protocol above i added also one more value the withExpense (yours could be something else)


@class PKAExpensesCell;
@class PKAExpenses;

@protocol ExpensesCellDelegate <NSObject>
- (void) expensesCell:(PKAExpensesCell *) cell payButtonPressed:(UIButton *) btn withExpense:(PKAExpenses *) expens;
@end

2. On .h of custom cell  create a delegate property and one for each other extra values you have added  on the above protocol
@property (nonatomic, assign) id<ExpensesCellDelegate> delegate;
@property (nonatomic, strong) PKAExpenses * expense;

3. Create an IBaction for the button you want to get the action (connect them properly)
- (IBAction)payButtonPressed:(id)sender;


4. Implement synthesize and the button action on .m of cell button file. 
@synthesize delegate,payButton,expense;

5.Implement the payButtonPressed methode at .m of cell 
- (IBAction)payButtonPressed:(id)sender {
    if (delegate && [delegate respondsToSelector:@selector(expensesCell: payButtonPressed: withExpense:)])
    {
        [delegate expensesCell:self payButtonPressed:payButton withExpense:expense];
    }
}

6. At viewController that has the tableview at .h file tell that viewController conforms the above protocole you have created. 
#import "PKAExpensesCell.h"

@interface PKAExpensesManagmentViewController : UIViewController <UITableViewDelegate, UITableViewDataSource, UITabBarDelegate, ExpensesCellDelegate>


7. At m. file of viewController at cell for row methode put the delegate
[cell setDelegate:self];
[cell setExpense:mylocalexpense];

8. Finally implement the required method from protocol at .m file of viewController and remember to reload data of mytableview if any data changed and need to be visible the effect. 
#pragma delegateProtocolForButtonsofCell
- (void) expensesCell:(PKAExpensesCell *) cell payButtonPressed:(UIButton *) btn withExpense:(PKAExpenses *)expens
{

    [expens setPaid:![expens paid]];
    [[self mytableview] reloadData];
    ........
}


In that way an user action on objects A view can create changes on object B view (etc).
The concept is
  • The B defines on A that is his delegate. 
  • The A when the action happened call one methode from his delegate. 
  • To ensure that B has that methode both of them follow the same protocol and more specific the A defines the protocol must be followed and the B conform it. 
I hope that will help someone :) 

best regards
Kostapappas

P.s. Most of the above solution is part of internet gathering solutions
PS2 The <NSOBJECT> at protocol is to ensure that compiler will understood the respondsToSelector method of delegate (because the delegate is <id>).