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!
Related
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];
}
The below code for the most part works when selecting items, the bar button enables, but as soon as I unselect 1 with say 3 still selected, it disables.
How can I use the below code to disable when the count reaches 0 items selected?
- (void)assetsTableViewCell:(WSAssetsTableViewCell *)cell didSelectAsset:(BOOL)selected atColumn:(NSUInteger)column
{
NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
// Calculate the index of the corresponding asset.
NSUInteger assetIndex = indexPath.row * self.assetsPerRow + column;
WSAssetWrapper *assetWrapper = [self.fetchedAssets objectAtIndex:assetIndex];
assetWrapper.selected = selected;
// Update the state object's selectedAssets.
[self.assetPickerState changeSelectionState:selected forAsset:assetWrapper.asset];
// Update navigation bar with selected count and limit variables
dispatch_async(dispatch_get_main_queue(), ^{
if (self.assetPickerState.selectionLimit) {
self.navigationItem.title = [NSString stringWithFormat:#"%# (%lu/%ld)", [self.assetsGroup valueForProperty:ALAssetsGroupPropertyName], (unsigned long)self.assetPickerState.selectedCount, (long)self.assetPickerState.selectionLimit];
}
});
}
Below is what needs adjusting.
if (selected == 1) {
self.navigationItem.rightBarButtonItem.enabled = YES;
} else if (selected == 0) {
self.navigationItem.rightBarButtonItem.enabled = NO;
}
selected will give you the state of the current asset so it wouldn't be wise to check this.
We need to check for some kinda global thing; basically to check for previous selections.
Looking at your navigationItem.title, it seems assetPickerState.selectedCount should do the trick.
So... maybe this?? (not sure but anyways...)
if (self.assetPickerState.selectedCount == 0) {
self.navigationItem.rightBarButtonItem.enabled = NO;
}
else {
self.navigationItem.rightBarButtonItem.enabled = YES;
}
Looks like you're only explicitly enabling the button when you have 1 selected (not more than that). Just going out on a whim but this might work (only disable if zero, otherwise enable it).
if (selected == 0) {
self.navigationItem.rightBarButtonItem.enabled = NO;
} else {
self.navigationItem.rightBarButtonItem.enabled = YES;
}
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");
}
}
I am working on a small converter app for my school project, an app that won't be published in App Store, just for school grade. I am wondering if anyone knows how did this developer in this app
made connections for converting values? The simplest way i can imagine is with switch cases but that would make too much unnecessary code:
if (first column is distance) then if(second column is metres)
case0:third column is yards -> do something
case1:third column is kilometers ->do something
case2:third column is metros ->do nothing
etc....
Thanks for answering.
EDIT:
Thanks for fast answer, this is what i made so far, iOS simulator is displaying correctly three column picker in which second two are displayed depending on the row of the first one. Can u tell me is this any good? Maybe some things are uneccesary complicated?
#import "konverterViewController.h"
#interface konverterViewController ()
#end
#implementation konverterViewController
- (void)viewDidLoad
{
[super viewDidLoad];
self.fizVelicine = [[NSArray alloc] initWithObjects:#"distance",#"mass" , nil];
self.udaljenostJedinice = [[NSArray alloc] initWithObjects:#"meter", #"kilometer", #"yard", #"inch", nil];
self.masaJedinice = [[NSArray alloc] initWithObjects:#"kilogram",#"dekagram",#"gram",#"tone" , nil];
}
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
{
UILabel *retval = (id)view;
if (!retval) {
retval = [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f,
[pickerView rowSizeForComponent:component].width,
[pickerView rowSizeForComponent:component].height)];
}
retval.opaque = NO;
retval.backgroundColor = [UIColor orangeColor];
retval.adjustsFontSizeToFitWidth = YES;
retval.font = [UIFont systemFontOfSize:12];
if (component == 0) {
retval.textAlignment = NSTextAlignmentCenter;
retval.text = [self.fizVelicine objectAtIndex:row];
}
else if ([self.odabir isEqualToString:#"distance"]){
retval.textAlignment = NSTextAlignmentCenter;
retval.text = [self.udaljenostJedinice objectAtIndex:row];
}
else {
retval.textAlignment = NSTextAlignmentCenter;
retval.text = [self.masaJedinice objectAtIndex:row];
}
return retval;
}
// returns the number of 'columns' to display.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 3;
}
// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent: (NSInteger)component
{
if(component== 0)
{
return [self.fizVelicine count];
}
else
{
if([self.odabir isEqualToString:#"distance"]){ return [self.udaljenostJedinice count];}
else {return [self.masaJedinice count];}
}
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if(component == 0)
{
return [self.fizVelicine objectAtIndex:row];
}
else {
if([self.odabir isEqualToString:#"distance]){
return [self.udaljenostJedinice objectAtIndex:row];}
else {
return [self.masaJedinice objectAtIndex:row];
}
}
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (component == 0) {
self.odabir=[[NSString alloc] initWithFormat:#"%#" , [self.fizVelicine objectAtIndex:row]];
[pickerView reloadAllComponents];}
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
It sounds like you're puzzling over how to initialize the picker sections at the top. I think you'll need a data structure that is an array of arrays:
#[#"distance", #[#"meters", #"inches", #"cubits", #"whatevers"],
#"weight", #[#"grams", // etc
Tell the picker that you have three segments. The first segment can be manufactured (and cached, if you want) as the first elements of each sub-array. The second two segments get their values from the data structure, indexed by the value of the first section.
EDIT; You'll probably want a data structure that helps you compute the conversion. For each kind of measure, imagine an NxN table, where N is the number of units on the wheels. A row let's you look up the left wheel setting and the column lets you look up the right wheel. The table should contain what you need to do the calculation. If all of the measures linearly related, like inches-meters, the table can simply contain floats (wrapped as NSNumber) conversion factors.
// conversion factors for distance, units as the first value, conversion factors in a subarray
// meters = 1*meters, 39.37*inches, 2.19*cubits, etc
NSArray *conversions =
#[#"meters", #[#1.0, #39.37, #2.19, //etc
#"inches", // etc. conversions to meters inches cubits etc.
You might notice that this array contains some waste. Only half the table is needed, since inches->meters is just the reciprocal of meters->inches) but I think the space small enough to not worry about this. You might also notice that the table is good only for simple linear relationships between units. Centigrade to Fahrenheit will require a different treatment. The most general treatment for arbitrary conversions might be an array of blocks that carry out the computation. But I suggest starting more simply.
EDIT AGAIN:
Now, to get a conversion formula, get the current picker selections and look up a conversion factor:
NSInteger fromUnitsIndex = [self.picker selectedRowInComponent:1];
NSArray *fromArray = self.conversions[fromUnitsIndex];
// the second member of this array is an array of conversion factors
NSArray *conversionNumbers = fromArray[1];
NSInteger toUnitsIndex = [self.picker selectedRowInComponent:2];
NSNumber *conversionNumber = conversionNumbers[toUnitsIndex];
It sounds like a fun project. Good luck!
For one of my last school projects, I am creating an iPad/iPhone application. For some days now I've been working on an issue with a certain memory leak. My application starts out on a specific view-controller (VCMainStatistics_iPad). From there, I push another view-controller (VCSocialMedia_iPad). Afterwards, I go back to the first view-controller.
When I repeat this sequence, I notice (by using Instruments - Activity Monitor) that the memory usage of the app keeps increasing. By disabling parts of the code, I eventually found out it has something to do with the pickerView. This code gives no leaks:
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return 0;
}
However, when I increase the number of rows, leaks start emerging (roughly 0.07 MB per row). Obviously, this is why I believe the pickerView is the cause of the leaks. I've been trying to remove the subviews from the pickerView before deallocation, setting pickerView to nil, and lots of other things... nothing fixes the issue. To hopefully make things a bit clearer, I'll post some more code.
The header file:
#import "UniversalViewController.h"
#define DATATYPE_SOCIALMEDIA 0
#interface VCSocialMedia_iPad : UniversalViewController <UIPickerViewDataSource, UIPickerViewDelegate>
{
NSArray *lMediaTypes;
NSMutableArray *lMediaData;
__weak IBOutlet UIPickerView *pkSocialMedia;
__weak IBOutlet UILabel *lblGraph;
}
#end
PickerView delegate methods:
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
// Get key of requested row
NSString *title = [[lMediaTypes objectAtIndex:row] capitalizedString];
// Capitalize first letter
title = [title capitalizedString];
// Return
return title;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
// Make or clear data lists
if( lGraphDayDataX[iSelectedServerIndex][DATATYPE_SOCIALMEDIA] == nil ){
lGraphDayDataX[iSelectedServerIndex][DATATYPE_SOCIALMEDIA] = [[NSMutableArray alloc] init];
}
else{
[lGraphDayDataX[iSelectedServerIndex][DATATYPE_SOCIALMEDIA] removeAllObjects];
}
if( lGraphDayDataY[iSelectedServerIndex][DATATYPE_SOCIALMEDIA] == nil ){
lGraphDayDataY[iSelectedServerIndex][DATATYPE_SOCIALMEDIA] = [[NSMutableArray alloc] init];
}
else{
[lGraphDayDataY[iSelectedServerIndex][DATATYPE_SOCIALMEDIA] removeAllObjects];
}
// Get required key
NSString *dictKey = [lMediaTypes objectAtIndex:row];
if( [dictKey isEqualToString:#"total_views"] ){
return;
}
// Adjust graph label
lblGraph.text = [NSString stringWithFormat:#"Stats from %#", dictKey];
// Get data of selected row
NSArray *mediaData = [lMediaData objectAtIndex:row];
// Add each day to data lists: inversed order
for( int day = [mediaData count]-1; day >= 0; day-- ){
NSDictionary *dayData = [mediaData objectAtIndex:day];
dictKey = #"wpsd_trends_date";
NSString *date = [dayData objectForKey:dictKey];
// Remove 00:00:00
date = [date stringByReplacingOccurrencesOfString:#" 00:00:00" withString:#""];
[lGraphDayDataX[iSelectedServerIndex][DATATYPE_SOCIALMEDIA] addObject:date];
dictKey = #"wpsd_trends_stats";
NSString *stats = [dayData objectForKey:dictKey];
[lGraphDayDataY[iSelectedServerIndex][DATATYPE_SOCIALMEDIA] addObject:stats];
}
// Update the graphs
[self updateGlobalScreen];
}
PickerView datasource methods:
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [lMediaTypes count];
}
Deallocation:
- (void)dealloc
{
pkSocialMedia = nil;
lblGraph = nil;
lMediaData = nil;
lMediaTypes = nil;
}
I only recently converted the project to Objective-C ARC, so there is a good chance this issue has something to do with my lack of experience with the concept. Apart from that, this is also my first Xcode project ever. Hopefully, someone here can help out: please let me know if I need to post more code to clarify things.
Thanks in advance!
Try removing the -(void)dealloc method. It shouldn't be implemented when you're using ARC. If you aren't using ARC, it needs to call [super dealloc].
Never found the solution itself, so I used a workaround: by replacing the NSPickerView with a NSTableView component, the leak did not occur anymore. For everyone who noticed the issue and tried to find a solution: thank you for trying!
I'm having a similar issue. It only happens when the UIPickerView is outside the bounds. The way I fixed it is to never have the UIPickerView move out of bounds (simply fade in and fade out to unhide/hide the UIPickerView). Probably a bug in UIKit.