I'm new to objective c and need some help. I've only one view controller which should show when as default an array called factbook. However I'd like to change the array by an alert validation. So that if the user would like to see sport he could just click on sport on the alert view and the current view controller would change the theme name to sport, the background color to the color scheme i'd like for the sport theme and the text to the sport facts array. Every help is welcome!
- (void)viewDidLoad {
[super viewDidLoad];
// init for displaying facts
self.factBook = [[FactBook alloc] init];
self.colorWheel = [[ColorWheel alloc] init];
self.view.backgroundColor = [self.colorWheel randomColor];
self.funFactLabel.text = [self.factBook randomFact];
}
- (IBAction)showFunFact:(UIButton *)sender {
self.view.backgroundColor = [self.colorWheel randomColor];
funFactLabel.text = [self.factBook randomFact];
}
- (IBAction)changeTheme:(UIButton *)sender {
// to sport
[changeThemeNotification addButton:#"change to sport" validationBlock:^BOOL{
BOOL passedValidation = true;
return passedValidation;
} actionBlock:^{
// segue to sport
self.themeName.text = #"Sport";
self.sportFactBook = [[SportFactBook alloc] init];
self.sportColorWheel = [[SportColorWheel alloc] init];
// not working
// self.funFactLabel = [self.sportFactBook randomSportFact];
self.view.backgroundColor = [self.sportColorWheel randomColor];
}];
//...
}
Assuming that this comment
// not working
// self.funFactLabel = [self.sportFactBook randomSportFact];
is the part you want to fix. If you are updating a label, just change its text
self.funFactLabel.text = [self.sportFactBook randomSportFactText];
randomSportFactText should return an NSString*.
If you set the output to a new label object, that doesn't update the view -- it just disassociates the outlet from the label in the view.
If you want to change just the backgroundColor, you can do that too:
self.funFactLabel.backgroundColor = [UIColor redColor];
Related
I am using NIDropworn in a strip of view the problem is the drop-down table is coming over another view which I have just placed below the drop-down view.
I am unable to select and and do any operation on the drop down table .
Is there a way that I can add the drop-down in the second view.
now the dropdown is coming on the small strip of view.
For example: I am having the dropDown menu in the header of a page which is view1.and the dropdown table is coming on the body which is view2.
You may not have added the NIDropDown in your view.
- (IBAction)btn_click:(id)sender {
NSArray * arr = [[NSArray alloc] init];
arr = [NSArray arrayWithObjects:#"None",#"Name",#"Date",nil];
// NSArray * arrImage = [[NSArray alloc] init];
if(dropDown == nil) {
CGFloat f = 130;
dropDown = [[NIDropDown alloc]showDropDown:sender :&f :arr :nil :#"down"];
dropDown.delegate = self;
dropDown.userInteractionEnabled=YES;
[self.viewBelowDD addSubview:dropDown]; // may be missing this line
[self.viewBelowDD bringSubviewToFront:dropDown];
}
else {
[dropDown hideDropDown:sender];
[self rel];
}
}
Hope that helps. Let me know if this doesn't work.
In my table cells, there is a button that displays a drop-down menu when you click on it. The problem is, the drop-down menu exceeds the height of the cell and bleeds into the cell below.
In that case, if I click the item in the drop-down, it actually acts as I clicked the cell below.
I tried using the code below but it doesn't seem to work.
[super bringSubviewToFront:dropDown];
[super willMoveToSuperview:dropDown];
The function that shows the drop-down is defined in the custom class for the table cell:
- (IBAction)eventAction:(id)sender {
NSArray * arr = [[NSArray alloc] init];
arr = [NSArray arrayWithObjects:#"Hello 0", #"Hello 1",nil];
NSArray * arrImage = [[NSArray alloc] init];
arrImage = [NSArray arrayWithObjects:[UIImage imageNamed:#"apple.png"], [UIImage imageNamed:#"apple2.png"], nil];
if(dropDown == nil) {
CGFloat f = 100;
dropDown = [[NIDropDown alloc]showDropDown:sender :&f :arr :arrImage :#"down"];
dropDown.delegate = self;
dropDown.layer.zPosition = 1;
[super bringSubviewToFront:dropDown];
[super willMoveToSuperview:dropDown];
}else {
[dropDown hideDropDown:sender];
[self rel];
}
}
Any help is greatly appreciated!!
Thank you!!
Rather than being a case of views being on top of each other, I think it might be that the touch is being interpreted by the table cell below as well.
Try disabling user interaction in the table view when the eventAction is fired.
tableView.userInteractionEnabled = NO;
And then turn it back on when the drop down view is dismissed.
I have a view controller containing 2 text fields, 2 segmented controls and a few labels which display time stamps set by the user using UIButtons. I would like to be able to restore any user set values for these items upon quit / restart, as well as when going back to my main menu view controller, which is a navigation controller. Using the following code, I am able to restore one of the text fields on background / terminate / restart, but I am unsure as to how to accomplish this for my other text field or the time stamp labels and segmented controls. I have tried to duplicate the restoration code with changes for the text field name and the #"UnsavedText" string with no luck.
Furthermore, whenever I go back to the main menu using the back button in the navigation bar, I lose all of my data from all fields.
Here is the code in my delegate, opting in to state restoration:
// Sets RESTORATION
-(BOOL)application:(UIApplication *)application shouldRestoreApplicationState:(NSCoder *)coder
{
return YES;
}
-(BOOL)application:(UIApplication *)application shouldSaveApplicationState:(NSCoder *)coder
{
return YES;
}
Here is the relevant code in my view controller to restore the one text field. I am including my viewDidLoad code with state initialization in case that is somehow part of the problem:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
// Updates time on currentTimeLabel
[self updateTime];
// Sets initial button states
[self setInitialState];
// Sets UITextField delegate
self.startLevel.delegate = self;
self.stopLevel.delegate = self;
// initializes basic values for segmented controls
bigTank = YES;
startFractions = #"";
stopFractions = #"";
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
// Restoration of text fields
-(void)encodeRestorableStateWithCoder:(NSCoder *)coder
{
// start level text
[coder encodeObject:_startLevel.text forKey:#"UnsavedText"];
[super encodeRestorableStateWithCoder:coder];
}
-(void)decodeRestorableStateWithCoder:(NSCoder *)coder
{
// start level text
_startLevel.text = [coder decodeObjectForKey:#"UnsavedText"];
[super decodeRestorableStateWithCoder:coder];
}
// Sets initial button and label states
- (void)setInitialState
{
self.start.enabled = YES;
self.stop.enabled = NO;
self.calculate.enabled = NO;
self.resume.enabled = NO;
// Text for time labels reset
_startTimeLabel.text = #"- -:- -:- -.- -";
_stopTimeLabel.text = #"- -:- -:- -.- -";
// Resets the minuteRateLabel
_minuteRateLabel.text = #"--.--";
// Resets the text fields to their initial state with the placeholder "inches" text
[_startLevel setText:nil];
[_stopLevel setText:nil];
// Resets inch levels to EVEN
[self.startFractionControl setSelectedSegmentIndex:0];
[self.stopFractionControl setSelectedSegmentIndex:0];
startFractions = #"";
stopFractions = #"";
}
Thanks in advance!
EDIT:
This is the code I tried per the suggestion:
My button click should ostensibly save the time stamp value:
- (IBAction)startButton:(UIButton *)sender
{
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"hh:mm:ss.SS"];
_startTimeLabel.text = [formatter stringFromDate:[NSDate date]];
UIButton *startButton = (UIButton *)sender;
// Creates the start time stamp for use in the calculation
startTime = [NSDate timeIntervalSinceReferenceDate];
// sets button states
startButton.enabled = NO;
stop.enabled = YES;
// Hides keypad on startButton click
[self.startLevel resignFirstResponder];
[self.stopLevel resignFirstResponder];
// saves the value for restoration using user defaults
NSDateFormatter *startTimeSave = formatter;
[[NSUserDefaults standardUserDefaults]
setObject:startTimeSave forKey:#"startTimeSaver"];
}
You can save your text values using user defaults. Here is a sample code snippet:
NSString *valueToBeSaved = #"someValue";
[[NSUserDefaults standardUserDefaults]
setObject:valueToBeSaved forKey:#"preferenceName"];
And for retrieving your value later, use this:
NSString *savedValue = [[NSUserDefaults standardUserDefaults]
stringForKey:#"preferenceName"];
I was looking into adding a UILabel property into a UIButton as a subview, matching the functionality of the titleLabel property currently present, and giving it all the different states of the button (UIControlStateNormal, UIControlStateHighlighted, etc.).
I started playing around with storing the states in a NSDictionary using the state (wrapped in a NSNumber) as the key to the dictionary with the values being the text, text colour and shadow colour. But I'm not sure this would work correctly based on the various different button state combinations.
So far I've got a the following methods:
-(void)setSelected:(BOOL)selected
{
super.selected = selected;
[self stateUpdated];
}
-(void)setHighlighted:(BOOL)highlighted
{
super.highlighted = highlighted;
[self stateUpdated];
}
-(void)setEnabled:(BOOL)enabled
{
super.enabled = enabled;
[self stateUpdated];
}
-(void)stateUpdated
{
[self updateValueLabel];
}
-(void)setValueText:(NSString *)text forState:(UIControlState)state
{
NSMutableDictionary *stateValues = self.customStates[#state];
// If we haven't set the state before create a new place to store them
if (!stateValues) {
stateValue = [NSMutableDictionary dictionary];
self.customStates[#state] = stateValues;
}
if (text) {
stateValues[#"text"] = text;
} else {
[stateValues removeObjectForKey:#"text"];
}
[self updateValueLabel];
}
-(void)setValueTextColor:(UIColor *)textColor forState:(UIControlState)state
{
NSMutableDictionary *stateValues = self.customStates[#state];
// If we haven't set the state before create a new place to store them
if (!stateValues) {
stateValues = [NSMutableDictionary dictionary];
self.customStates[#state] = stateValues;
}
if (text) {
stateValues[#"textColor"] = textColor;
} else {
[stateValues removeObjectForKey:#"textColor"];
}
[self updateValueLabel];
}
-(void)updateValueLabel
{
NSMutableDictionary *currentStateValues = self.customStates[#self.state];
// Set the new values from the current state
self.valueLabel.text = currentStateValues[#"text"];
self.valueLabel.textColor = currentStateValues[#"textColor"];
}
I have the valueLabel as a property on the UIButton subclass.
The different attributes set for the different states don't seem to be taking effect. If I set them all manually with different bitmasks its fine, but I want to emulate the default fallback states as UIButton does for its properties.
So instead of having to set each one manually:
[button setValueText:#"Normal" forState:UIControlStateNormal];
[button setValueText:#"Normal" forState:UIControlStateHighighted];
I want to be able just to set the title once:
[button setValueText:#"Normal" forState:UIControlStateNormal];
And it show for all states.
Thanks in advance!
Create a getter valueTextForState:, like Apple does with titleForState:. The documentation for this method's return value reads:
The title for the specified state. If no title has been set for the specific state, this method returns the title associated with the UIControlStateNormal state.
So, let's do this as well for your property:
- (NSString *)valueTextForState:(UIControlState)state
{
NSString *result;
NSDictionary *currentStateValues;
currentStateValues = self.customStates[#(state)];
result = currentStateValues[#"text"];
if (!result && state != UIControlStateNormal) {
// Fall back to normal state.
currentStateValues = self.customStates[#(UIControlStateNormal)];
result = currentStateValues[#"text"];
}
return result;
}
You would do the same for your color. Then your updateValueLabel would look like this:
-(void)updateValueLabel
{
// Set the new values from the current state
self.valueLabel.text = [self valueTextForState:self.state];
self.valueLabel.textColor = [self valueColorForState:self.state];
}
How can I pass data from UINavigationController to The root UITableViewController?
I have implemented the ECSlidingViewController (https://github.com/edgecase/ECSlidingViewController). User selects one of the cells in the menu that correspond to different urls I want to display information from on my tableView that sitts on top of the UINavigationController. (u know the default combination that u get my dragging UINavigationController to ur storyboard). I am able to get the data from the sliding menu to my navigationController now I am trying to pass that same info on my tableview?
In my menu I have:
UINavigationController *newTopViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"NavigationTop"];
newTopViewController = [(NavigationTopViewController*)newTopViewController initWithCinema:self.myCinema];
In UINaviationController:
- (id)initWithCinema:(Cinema *)cinema {
self = [super init];
if(self) {
_myCinema = [[Cinema alloc] init];
_myCinema = cinema;
}
return self;
}
- (void) viewDidLoad {
[super viewDidLoad];
// this log works I get the info to here.
NSLog(#"url(navigation):%#", self.myCinema.cinemaURL);
//MoviesTableViewController *moviesTableViewController = [[MoviesTableViewController alloc] initWithCinema:self.myCinema];
//UITableViewController *newTopViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"MoviesTable"];
//NavigationTopViewController *newTopViewController = [[NavigationTopViewController alloc] initWithCinema:self.myCinema];
//newTopViewController = [(MoviesTableViewController *)newTopViewController initWithCinema:self.myCinema];
//[self performSegueWithIdentifier:nil sender:self.myCinema];
[self prepareForSegue:nil sender:self.myCinema.cinemaURL];
}
In my UITableView:
- (void)setCinema:(Cinema *)cinema {
// works here too
NSLog(#"Table(setCinema):%#", cinema.cinemaURL);
self.myCinema = [[Cinema alloc] init];
if(!cinema) {
cinema.cityIndex = kAstanaIndex;
cinema.name = kKeruen;
cinema.nameForText = kKeruenText;
cinema.cinemaURL = kKeruenURL;
cinema.cinemaURLTomorrow = kKeruenURLtomorrow;
}
self.myCinema = cinema;
// works here too!!!
NSLog(#"Table(myCinema):%#", self.myCinema.cinemaURL);
}
However its gone in viewDidLoad:
- (void)viewDidLoad
{
[super viewDidLoad];
// set delegate to self
self.tableView.delegate = self;
// set loading theater's url
// does not work here: I GET NULL !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
NSLog(#"url(moviesTable):%#", self.myCinema.cinemaURL);
_model = [[MovieModel alloc] initWithURL:self.myCinema.cinemaURL];
}
None of the methods I have tried (commented in Navigation worked...) at least for me. Please give me any suggestions. Thank you in advance.
UINavigationController does not hold any data, but rather a stack of view controllers. I'd recommend you check out frameworks such as the free Sensible TableView. The framework will automatically handle detail view generation and passing data between them. Saves me tons of development time in my projects.