I'm working on slide out menu bar in objective-c. I have used some classes from this link https://github.com/arturdev/AMSlideMenu . I had made left menu. Now the problem which I'm facing is that the items in left menu are Home , AboutUs, Login/Register and Contact . if user get login the item login/register should change to logout and above the Home their should appear a cell of user profile or user till it remain login. If user press logout item it should logout and take us to home screen. Can anybody help me? I'm login the user data from web service. The left menu bar items r made in static cells.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(refreshList)
name:#"refreshList"
object:nil];
if ([[[[NSUserDefaults standardUserDefaults] dictionaryRepresentation] allKeys] containsObject:#"userlogging"]) {
NSString *login = [[NSUserDefaults standardUserDefaults] objectForKey:#"userlogging"];
if ([login isEqualToString:#"loggedin"]) {
NSArray *titles = #[#"Search Restaurants",#"Change Language",#"Sellers click here",#"Login"];
checklogin = YES;
}
}
else
{
NSArray *titles = #[#"Search Restaurants", #"My Cart", #"Favorite Restaurants", #"Previous Orders",#"Change Language",#"Sellers click here", #"My Profile", #"Logout"];
checklogin = NO;
}
[self.tableView reloadData];
In left menu you should write a function that prepares the data source for your table view based on user state (log in/log out) and on log out menu reload table view.
e.g., a psuedocode to give you an idea:
var dataSource: [CustomMenuItemObject] = []
func prepareDataSource()
{
dataSource = []
if(MySessionManager.current.isUserLoggedIn())
{
dataSource.append (createMyProfileMenu())
dataSource.append (createAboutUsMenu())
dataSource.append (createLogoutMenu())
dataSource.append (createContactMenu())
}
else
{
dataSource.append (createHomeMenu())
dataSource.append (createAboutUsMenu())
dataSource.append (createLoginRegisterMenu())
dataSource.append (createContactMenu())
}
myTableView.reloadData()
}
func tableView(....numberOfRows...)
{
return dataSource.count
}
func tableView(....cellForRow...)
{
let cell == tableView.dequeue...
...
...
cell.updateCustomCellUsing(dataSource[indexPath.row])
...
...
return cell
}
func createMyProfileMenu() -> CustomMenuItemModel
{
let item = CustomMenuItemModel()
item.titleText = "Profile"
...
...
return item
}
..
.. // Further menu item creation code
func userDidLogout() // Delegate or NSNotification callback
{
MySessionManager.current.clearUserDataFromSession()
prepareDataSource()
myTableView.reloadData()
}
func userDidLogIn() // Delegate or NSNotification callback
{
MySessionManager.current.setupUserInSession()
prepareDataSource()
myTableView.reloadData()
}
On pressing logout either use NSNotification or delegate to reload the tableview in left menu view controller.
EDIT: Objective-C version
NSMutableArray dataSource = [NSMutableArray new];
-(void)prepareDataSource
{
dataSource = [NSMutableArray new];
if([[MySessionManager current] isUserLoggedIn])
{
[dataSource addObject:[self createMyProfileMenu]];
[dataSource addObject:[self createAboutUsMenu]];
[dataSource addObject:[self createLogoutMenu]];
[dataSource addObject:[self createContactMenu]];
}
else
{
[dataSource addObject:[self createHomeMenu]];
[dataSource addObject:[self createAboutUsMenu]];
[dataSource addObject:[self createLoginRegisterMenu]];
[dataSource addObject:[self createContactMenu]];
}
[myTableView reloadData];
}
-(void)tableView(....numberOfRows...)
{
return dataSource.count;
}
-(void)tableView(....cellForRow...)
{
let cell == tableView.dequeue...
...
...
[cell updateCustomCellUsing(dataSource[indexPath.row])];
...
...
return cell
}
-(CustomMenuItemModel *)createMyProfileMenu
{
CustomMenuItemModel *item = [CustomMenuItemModel new];
item.titleText = "Profile";
...
...
return item
}
..
.. // Further menu item creation code
-(void)userDidLogout // Delegate or NSNotification callback
{
[[MySessionManager current] clearUserDataFromSession];
[self prepareDataSource];
[myTableView reloadData];
}
-(void)userDidLogIn // Delegate or NSNotification callback
{
[[MySessionManager current] setupUserInSession];
[self prepareDataSource];
[myTableView reloadData];
}
Related
In my VC I have a UITableView. Each cell has a UITableView as one of its contents. Timer is set updating each cell every 10secs. Events are handled which also reloads the respective cell.
Method that timer calls :-
-(void) updateVisitotsLists {
NSLog(#"UPDATING VISITORS LIST ***************************");
// Call API's to get lists
[api getVisitorsList];
// Init Arrays
browsingList = [MainAppDataObject sharedAppDataObject].visitors_browsingList;
secondList = [MainAppDataObject sharedAppDataObject].visitors_secondList;
thirdList = [MainAppDataObject sharedAppDataObject].visitors_thirdList;
fourthList = [MainAppDataObject sharedAppDataObject].visitors_fourthList;
// AS these are no more useful, so make it nil & save memory
[MainAppDataObject sharedAppDataObject].visitors_browsingList = nil;
[MainAppDataObject sharedAppDataObject].visitors_secondList = nil;
[MainAppDataObject sharedAppDataObject].visitors_thirdList = nil;
[MainAppDataObject sharedAppDataObject].visitors_fourthList = nil;
// Reload all lists with latest data
[self reloadBrowsingRow];
[self reloadSecondRow];
[self reloadThirdRow];
[self reloadFourthRow];
}
Event Handler Method :-
-(void) handleNewVisitor : (NSNotification *) notification {
// UPDATE VISITOR'S LIST
Visitor *v = [notification object];
#try {
if (v != nil) {
// Add V to browsing list
[browsingList addObject:v];
// Reload browsing list
[self reloadBrowsingRow];
}
}#catch (NSException *e) {
NSLog(#"EXCEP - %#", e);
}
v = nil;
return;
}
Reloading Method -
-(void)reloadBrowsingRow {
// Browsing
VisitorsListsCell *bcell = (VisitorsListsCell*)[self.visitorlistsTv cellForRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]];
[bcell.listsTableView reloadData];
[bcell updateButtonText];
[bcell setNeedsDisplay];
bcell = nil;
return;
}
The Problem :-
When updateVisitotsLists is called thru timer, the updated contents are not reflected on cell.
When event handler method calls the same [self reloadBrowsingRow]; method, the contents of the cell are updated and reflected.
Due to this despite cells contents are updated but are not reflected until the state of cell is changed - expanded or collapsed.
I tried removing timer and cell updates properly on event caught, but when timer was on and event was caught, method is called but contents are not reflected on the screen.
I feel both methods may be calling reload method at same time, hence this must be happening or what ? How can this be handled making sure that the contents of cells are updated in any respect ? Any help is highly appreciated. Thanks.
Use [tableview reloadData]; on that method.
Because Reload on tableView will reload all data, so it will be more helpful.
If my button is in the "selected" state, I want an activity indicator to appear to let the user know that something is happening and that my app is searching for data. I've tried to accomplish this FIRST by using NSLog to see if I can get this method working FIRST. So I did this:
- (void)viewDidLoad
{
[super viewDidLoad];
searchedItem.delegate = self;
if(searchButton.selected == YES)
{
NSLog(#"The button was selected");
}
}
For some reason, it won't work.
Put this checkmark in your button click event. It perfect work when click on button as first time then got to Not Selected and after click on second time go to Selected.
-(IBAction)ClickBtn:(UIButton *)sender
{
sender.selected = ! sender.selected;
if (sender.selected)
{
NSLog(#" Not Selected");
}
else
{
NSLog(#" Selected");
}
}
try this
- (void)viewDidLoad
{
[super viewDidLoad];
searchedItem.delegate = self;
[searchButton setSelected:YES];
if(searchButton.selected == YES)
{
NSLog(#"The button was selected");
}
}
So i have a switch and when it is "on" i would like the CPPickerView to switch to a particular value in an array. As well if the pickerview is moved again i would like the switch to move to the off position.
I know how to get the current day of the week and am trying to switch the pickerview selection to the current day of the week.
If i am way off base here asking such a generalised question just let me know or if you need any more information.
//CPPicker
self.daysOfWeekData = [[NSArray alloc] initWithObjects:#"Monday", #"Tuesday", #"Wednesday", #"Thursday", #"Friday", #"Saturday", #"Sunday", nil];
self.dayPickerView.allowSlowDeceleration = YES;
[self.dayPickerView reloadData];
#pragma mark - Horizontal pickerview
//DataSource
-(NSInteger)numberOfItemsInPickerView:(CPPickerView *)pickerView {
return 7;
}
-(NSString *)pickerView:(CPPickerView *)pickerView titleForItem:(NSInteger)item {
return daysOfWeekData[item];
}
//Delegate
-(void)pickerView:(CPPickerView *)pickerView didSelectItem:(NSInteger)item {
self.dayLabel.text = [NSString stringWithFormat:#"%#", daysOfWeekData[item]];
}
//Today's day date
- (IBAction)todaySwitchChange:(id)sender {
if (todaySwitch.on) {
NSLog(#"It is on");
} else {
NSLog(#"It is off");
}
}
This can be done by using CPPickerView's setSelectedItem:animated: method, along with the normal delegate methods.
In your todaySwitchChange: method when the switch is turned on, set the CPPickerView to your desired index:
//Today's day date
- (IBAction)todaySwitchChange:(id)sender {
if (todaySwitch.on) {
NSLog(#"It is on");
// This will cause the CPPickerView to select the item you choose
NSUInteger itemToSelect = someValue; //whatever logic you need to select the right index
[self.dayPickerView setSelectedItem:itemToSelect animated:YES]; // Or disable animation if desired
} else {
NSLog(#"It is off");
}
}
To toggle the switch off when the user scrolls on the CPPickerView, you'll need to hook into the delegate method which gives you notification that scrolling has occurred:
// Implement the following delegate method
- (void)pickerViewWillBeginChangingItem:(CPPickerView *)pickerView {
// Picker is going to change due to user scrolling, so turn the switch off
if (todaySwitch.on) {
todaySwitch.on = NO;
}
}
Hope this helps!
I am using UIActivityViewController to present sharing options and I want to display another view controller when the UIActivityViewController is dismissed by the user or when the animation that follows "activityDidFinish:(bool)completed" gets over. When I try to present the other controller in the completion handler of the UIActivityViewController, I get the following warning and the second VC does not get displayed at all!
Attempt to present <_UIViewController: 0x1e16f020> on <###> while a presentation is in progress!
UIActivityViewController activityVC = [[UIActivityViewController alloc]initWithActivityItems:selectedAssetsURL applicationActivities:nil];
[activityVC setCompletionHandler:^(NSString *activityType, BOOL completed) {
NSLog(#"completed");
//Present another VC
}];
The question is, how to know when the UIActivityViewController disappears from the screen? Even the -ViewDidAppear method of the view controller which presents the UIActivityViewController does not get fired!
In this link there's good information about how the UIActivityViewController works:
http://www.apeth.com/iOSBook/ch26.html#_activity_view
Basically you can subclass the UIActivityViewController into another class and implement a method to know when it has been dissmissed.
UIActivityViewController* avc =
[[UIActivityViewController alloc]
initWithActivityItems:#[myCoolString]
applicationActivities:#[[MyCoolActivity new]]];
Here’s the preparatory part of the implementation of MyCoolActivity:
-(NSString *)activityType {
return #"com.neuburg.matt.coolActivity"; // make up your own unique string
}
-(NSString *)activityTitle {
return #"Be Cool";
}
-(UIImage *)activityImage {
return self.image; // prepared beforehand
}
-(BOOL)canPerformWithActivityItems:(NSArray *)activityItems {
for (id obj in activityItems) {
if ([obj isKindOfClass: [NSString class]])
return YES;
}
return NO;
}
-(void)prepareWithActivityItems:(NSArray *)activityItems {
self.items = activityItems;
}
To perform the activity, we implement one of two methods:
-(void)performActivity {
// ... do something with self.items here ...
[self activityDidFinish:YES];
}
-(UIViewController *)activityViewController {
MustacheViewController* mvc = [MustacheViewController new];
mvc.activity = self;
mvc.items = self.items;
return mvc;
}
And then MustacheViewController would have code like this:
- (IBAction)doCancel:(id)sender {
[self.activity activityDidFinish:NO];
}
- (IBAction)doDone:(id)sender {
[self.activity activityDidFinish:YES];
}
Ok, after a few tries I finally populated the static table view with help from #jrturton ( how to populate a static UITableView ).
But now I have another problem.. It seems while the fields are populated, only visible fields are populated via the method I use. Other fields while populated via code, remains empty when scrolling down.
Is there something I'm missing? While filling dynamic tables via delegates are certain to solve the problem I'm seeing, I just don't want to fill all static texts (labels) via arrays etc. And I know there will always be 16 rows in the table.
So anyone having any suggestion to what went wrong?
Here is the code:
- (void)setDetailItem:(id)newDetailItem
{
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
}
}
-(void)setParam:(id)newparam
{
if (_param != newparam) {
_param = newparam;
// Update the view.
[self configureView];
}
if (self.masterPopoverController != nil) {
[self.masterPopoverController dismissPopoverAnimated:YES];
}
}
- (void)configureView
{
// Update the user interface for the detail item.
if (_detailItem) {
for (int idx=0; idx<16; idx++) {
NSString *value = [NSString stringWithFormat:#"%#",[_param objectAtIndex:idx]];
[self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:idx inSection:0]].detailTextLabel.text = value;
}
}
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Do any additional setup after loading the view, typically from a nib.
appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[self configureView];
}
I modified some lines from earlier code, and put some codes that might help understanding better.