IBInspectable property values not updating in xib - objective-c

I'm running into a minor complication using IBInspectable properties and not sure if it might have something to do with my xibs and xib usage. I'm trying to reuse a custom control between multiple view controllers. The control is a custom tab manager:
The IBInspectable Attributes are configured in this xib as: First, Second, Third.
Here is the corresponding code for the header file.
IB_DESIGNABLE
#interface TabContainerView : NSView
#property (nonatomic, strong) IBOutlet NSView *view;
#property (weak) IBOutlet TabContentView *contentView;
#property (weak) IBOutlet TabView *firstTab;
#property (weak) IBOutlet TabView *secondTab;
#property (weak) IBOutlet TabView *thirdTab;
#property (nonatomic, strong) IBInspectable NSString *tabOneText;
#property (nonatomic, strong) IBInspectable NSString *tabTwoText;
#property (nonatomic, strong) IBInspectable NSString *tabThreeText;
#end
#import "TabContainerView.h"
#interface TabContainerView ()
#property (nonatomic, strong) NSMutableArray *tabsArray;
#property (nonatomic, assign) NSInteger selectedTabIndex;
#property (weak) IBOutlet NSTextField *tabOneTextField;
#property (weak) IBOutlet NSTextField *tabTwoTextField;
#property (weak) IBOutlet NSTextField *tabThreeTextField;
#end
#implementation TabContainerView
#pragma mark Init
- (id)initWithFrame:(NSRect)frameRect {
NSString* nibName = NSStringFromClass([self class]);
self = [super initWithFrame:frameRect];
if (self) {
if ([[NSBundle mainBundle] loadNibNamed:nibName
owner:self
topLevelObjects:nil]) {
[self configureView];
}
}
return self;
}
#pragma mark Configure View
- (void)configureView{
[self.view setFrame:[self bounds]];
[self addSubview:self.view];
self.tabOneTextField.stringValue = self.tabOneText;
self.tabTwoTextField.stringValue = self.tabTwoText;
self.tabThreeTextField.stringValue = self.tabThreeText;
}
#end
This works fine in the TabContainerView.xib without issue. Now when I attempt to use this control in two different view controllers, I run into problems. Both of my view controllers are also loaded from Xibs.
In view controller 1 I have something like this:
In view controller 1 I've subclassed the custom view to the TabContainerView subclass which works just fine when I run the application. I've also changed the text to be specific for this view controller. List, Map, Filter are the IBInspectable property values for view controller one. In view controller 2 (not shown), I've done the exact same thing, however different IBInspectable property values specific for view controller 2. However, when I run the application the values never update and always stay as First, Second, and Third. I'm not sure if there is something I'm doing that's causing this problem but any help or tips would be appreciated. (IBDesignable seems to give me a lot of warnings where it breaks and not sure if maybe it's just loading the last saved value for the xib.)

Have you imported #import "TabContainerView.h" in controller 2 .h file.

Related

Root View Controller's child View Controllers are on top of root

I have what is a seemingly simple problem but I cannot find a solution! I have a subclass of UIViewController that is my root view controller, and ten different other UIViewcontrollers that I want to load in as child view controllers when called (one at a time, not all ten on screen at once.)
The root controller has a few buttons whose actions call the respective code to bring up a child view controller. The root view controller is loaded first by the nib and I want to instantiate it with page01ViewController as the first child. But whenever I call the following code, the child view controller is overlayed on top of my rootViewController, hiding all of the control buttons in my root controller!
// RDJrootPageViewController.m
#import "RDJrootPageViewController.h"
#import "RDJhomeScreenViewController.h"
#import "RDJpage01ViewController.h"
#import "RDJpage02ViewController.h"
#import "RDJpage03ViewController.h"
#import "RDJpage04ViewController.h"
#import "RDJpage05ViewController.h"
#import "RDJpage06ViewController.h"
#import "RDJpage07ViewController.h"
#import "RDJpage08ViewController.h"
#import "RDJpage09ViewController.h"
#import "RDJpage10ViewController.h"
#interface RDJrootPageViewController ()
#property (retain, nonatomic) RDJhomeScreenViewController *homeScreenViewController;
#property (retain, nonatomic) RDJpage01ViewController *page01ViewController;
#property (retain, nonatomic) RDJpage02ViewController *page02ViewController;
#property (retain, nonatomic) RDJpage03ViewController *page03ViewController;
#property (retain, nonatomic) RDJpage04ViewController *page04ViewController;
#property (retain, nonatomic) RDJpage05ViewController *page05ViewController;
#property (retain, nonatomic) RDJpage06ViewController *page06ViewController;
#property (retain, nonatomic) RDJpage07ViewController *page07ViewController;
#property (retain, nonatomic) RDJpage08ViewController *page08ViewController;
#property (retain, nonatomic) RDJpage09ViewController *page09ViewController;
#property (retain, nonatomic) RDJpage10ViewController *page10ViewController;
#end
#implementation RDJrootPageViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
currentPage = 1;
self.page01ViewController = [self.storyboard instantiateViewControllerWithIdentifier:#"page01"];
[_page01ViewController.view setFrame:CGRectMake(0, 0, 1024, 768)];
[self addChildViewController:_page01ViewController];
[self.view addSubview:_page01ViewController.view];
[_page01ViewController didMoveToParentViewController:self];
[self.view setUserInteractionEnabled:YES];
}
My problem is similar to the one asked here, but no solution was ever identified:
Return from Child View Controller to Container
Every tutorial I find has the same setup: make your new VC, add it as a childView to self, then add that as a subview to your root view, but it dosen't work.
Anyone know the right way to do this?
You may want to user insertSubview:atIndex:. Using an index of 0 will add the view under all the other views. Alternatively you could have a container view for the views of the page view controllers. This container view needs to be added at index 0 in the view of RDJrootPageViewController. The page view controllers views could be added to the afore mentioned container view.
Hope this helps.

How to add a UIView to an UIAlertView?

I have to create a custom AlertView with a view that contain some label. I create the .h and .m of CustomAlert
this is the CustomAlert.h.
#import <Foundation/Foundation.h>
#interface CustomAlert: UIView
#property (nonatomic, weak) IBOutlet UILabel *ok;
#property (nonatomic, weak) IBOutlet UILabel *ok1;
#property (nonatomic, weak) IBOutlet UILabel *ok2;
#property (nonatomic, weak) IBOutlet UILabel *ok3;
#property (nonatomic, weak) IBOutlet UILabel *ok4;
#property (nonatomic, weak) IBOutlet UILabel *ok5;
#end
and this is the CustomAlert.m.
#import "CustomAlert.h"
#implementation CustomAlert
#synthesize ok = _ok;
#synthesize ok1 = _ok1;
#synthesize ok2 = _ok2;
#synthesize ok3 = _ok3;
#synthesize ok4 = _ok4;
#synthesize ok5 = _ok5;;
#end
I also create the xib with just a view and i connect the label with all the "ok".
Now, i want to add this View to an AlertView with just an Ok button. How can i do it? I want to use it with ios 7 and 6.
Thanks!!
In iOS 7 you should not munge a UIAlertView like this - and there is no need, because thanks to custom view transitions you can make your own small presented view in front of your interface, so that it looks and acts like a UIAlertView but can contain anything you like.
I've written an online tutorial on how to do this:
http://programming.oreilly.com/2014/01/transcending-uialertview-on-ios-7.html
And there's a downloadable github project that goes with it:
https://github.com/mattneub/custom-alert-view-iOS7

UISwitch, if/else statement to filter TableView

So I'm creating a Settings view (SettingsViewController) for my app, and the view contains 5 switches. I'm looking to accomplish the following:
if switch is on, filter TableView to only display items that contain 'Arthritis'. if switch is off, display all items.
Note: the TableView is located on another view (ViewController).
Now even though I've imported ViewController.h onto my SettingsViewController.m file, it's telling me that StrainTableView is unidentified. Any idea as to why? See code below (you can ignore the PickerView references).
SettingsViewController.h
#interface SettingsViewController : UIViewController {
IBOutlet UISwitch *ArthritisSwitch;
IBOutlet UIView *CancerSwitch;
IBOutlet UISwitch *HIVSwitch;
IBOutlet UISwitch *InsomSwitch;
IBOutlet UISwitch *MigSwitch;
IBOutlet UILabel *mylabel;
NSArray *arthritisResults;
NSArray *Strains;
}
-(IBAction)switchtheswitch:(id)sender;
#property (nonatomic, retain) NSArray *arthritisResults;
#end
SettingsViewController.m
#import "SettingsViewController.h"
#import "ViewController.h"
#interface SettingsViewController ()
#end
#implementation SettingsViewController
#synthesize arthritisResults;
-(IBAction)switchtheswitch:(id)sender; {
if (ArthritisSwitch.on) {
NSPredicate *ailmentPredicate = [NSPredicate predicateWithFormat:#"title ==[c] 'Arthritis'"];
arthritisResults = [Strains filteredArrayUsingPredicate:ailmentPredicate];
// Pass any objects to the view controller here, like...
[StrainTableView setSearchResults: [arthritisResults copy]];
NSLog(#"%#", arthritisResults);
}
else {
[Strains count];
}
}
ViewController.h
#import "PickerViewController.h"
#interface ViewController : UIViewController <PickerViewControllerDelegate, UITableViewDataSource,UITableViewDelegate>
{
NSArray *searchResults;
// NSArray *Strains;
NSMutableData *data;
NSMutableArray *dataArray;
NSArray *Strains;
}
#property (nonatomic, strong) NSMutableArray * favoritesArray;
#property (nonatomic, retain) NSArray *searchResults;
#property (strong, nonatomic) IBOutlet UITableView *StrainTableView;
#end
Just importing a class does not allow you to use a property from that class. You need to get an instance of the ViewController class (let's call it vc for example), and then use it like so:
[vc.StrainTableView setSearchResults: [arthritisResults copy]];
How you make that instance of ViewController depends on the structure of your app. You probably don't just want to alloc init one, but get a reference to one that you already have.
BTW, your code would be easier to read and understand if you conform to the naming convention of using lowercase letters to start properties and methods (and capitals for classes).

Testing equality of UIViews, clarification needed

I am having trouble testing equality on the Views that are set up in my project.
This is a long post, please bear with me. I have 3 separate views set up as part of the same XIB.
Each view is connected to File Owner (UIViewController) via an IBOutlet
The owner itself is a UIViewController
#interface PuzzleViewController : UIViewController {
Inside the FileOwner views are declared as:
IBOutlet Puzzle1 *p1;
IBOutlet Puzzle2 *p2;
IBOutlet Puzzle3 *p3;
#property (nonatomic, retain) IBOutlet Puzzle1 *p1;
#property (nonatomic, retain) IBOutlet Puzzle2 *p2;
#property (nonatomic, retain) IBOutlet Puzzle3 *p3;
Additionally i have
UIView *currentPuzzleView;
#property (nonatomic, retain) UIView *currentPuzzleView;
In .m file, upon initialization, i declare current view to be p1
[self setCurrentPuzzleView:p1];
Later, i would like to check if current view is in fact p1. This comparison fails.
if ([[self currentPuzzleView] isEqual:p1]) {
Additionally this fails as well
if ([self currentPuzzleView] == p1) {
Why is this?
Because you are using different classes for the equality test (UIView and Puzzle1). Your currentPuzzleView should be a pointer to one of those three classes Puzzle1 Puzzle2 Puzzle3. If you definitely need to use three different classes for those puzzle views, try adding tags to them and change
#property (nonatomic, retain) UIView *currentPuzzleView;
to
int currentPuzzleViewTag;
set it to 1 upon viewDidLoad: and change the tag to appropriate when different views are selected.
It's just a hunch but perhaps p1 is nil 'upon initialization'. It really depends on where you set currentPuzzleView to p1. It could be that the outlet points to nothing (yet).

EXC_BAD_ACCESS when adding UINavigationController to window

I am working on an app using multiple view controllers and the navigation controller. When the application runs and executes the following code, it throws an exception when trying to add the sub view.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self.window addSubview:[navigationController view]];
[self.window makeKeyAndVisible];
}
I declare the navigation controller like so:
#interface SimpleContactsAppDelegate : NSObject <UIApplicationDelegate> {
NSManagedObjectModel *managedObjectModel;
NSManagedObjectContext *managedObjectContext;
NSPersistentStoreCoordinator *persistentStoreCoordinator;
UIWindow *window;
UINavigationController *navigationController;
// view for adding new contacts
UIViewController *newContactView;
UIButton *addButton;
// controls for the addContactView
UIButton *saveContactButton;
UITextField *nameField;
UITextField *emailField;
UITextField *phoneField;
UITableView *contactsTable;
}
#property (nonatomic, retain, readonly) NSManagedObjectModel *managedObjectModel;
#property (nonatomic, retain, readonly) NSManagedObjectContext *managedObjectContext;
#property (nonatomic, retain, readonly) NSPersistentStoreCoordinator *persistentStoreCoordinator;
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UINavigationController *navigationController;
#property (nonatomic, retain) IBOutlet UIButton *addButton;
#property (nonatomic, retain) IBOutlet UITableView *contactsTable;
// controller and fields for the form
#property (nonatomic, retain) IBOutlet UIViewController *newContactView;
#property (nonatomic, retain) IBOutlet UITextField *nameField;
#property (nonatomic, retain) IBOutlet UITextField *emailField;
#property (nonatomic, retain) IBOutlet UITextField *phoneField;
#property (nonatomic, retain) IBOutlet UIButton *saveContactButton;
I have connected the navigation controller to the Delegate object in the XIB. Feel free to have a look at my full source: https://github.com/agmcleod/SimpleContacts/tree/parttwo
I've tried using Instruments with NSZombie, but it doesnt seem to stop and let me inspect what has particularly gone wrong. It also just keeps running sometimes, and won't terminate. I end up having to force quit it using active terminal.
First of all, you declare a property, but access the UINavigationController through its instance variable instead of using the property.
Use this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[self.window addSubview:[self.navigationController view]];
[self.window makeKeyAndVisible];
return YES;
}
Second, you changed the name of your main nib file to "Window.xib". You either have to change it back to "MainWindow.xib" or you will have to edit your SimpleContacts-Info.plist and change the value for "Main nib file base name" to "Window".