How to include skins in ios app - ios

I developed a new iPad calculator and am working on an update for it that has a settings option where you can change the app's skin. Currently, I am using different UIViewControllers for that, but it is not the best solution.

To build on #MJN's answer, once you have selected a skin/theme class, you can easily apply it across your app using UIAppearance, which lets you set styles for all instances of common UIKit classes like UIButton, UIBarButtonItem, UINavigationBar, etc.

You can make an AppSkinProtocol that has methods like the following
- (NSString*)skinIdentifier;
- (UIColor*)highlightedButtonColor;
- (UIImage*)successfulDownloadAlertBackground;
Then make subclasses of NSObject that conform to your AppSkinProtocol.
You can then make a AppSkinManager to save the selected skin to NSUserDefaults. When the app launches load the skin with the identifier matching the string saved to defaults.

Related

How to create an instance of UIView from Watch Extension in watch OS 2?

In watch OS 1, I was able to create an instance of a custom view in WatchExtension. I'm not talking about showing it, I mean just creating an instance of the view and then create an UIImage with its content.
Now, in watch OS 2, I can't access to the UIView from WatchExtension, even when I have imported the UIKit framework.
Is there any way to be able to create an instance of UIView from WatchExtension?
It seems it's not possible on watchOS2 unfortunately. While watchOS1 used the iOS platform SDK, watchOS2 is a separate platform.
migration docs:
In watchOS 2, you can share code, but not frameworks, between your iOS app and Watch app. Because the apps run on separate platforms with different architectures...
Also in WatchKit in depth 1 wwdc video they mention this:
The WatchKit extension for watchOS 1 is something you have created already, there is a target in your project, but it uses the iOS platform in SDK.
Here are the available system technologies you can use on watchOS2.
I did the same thing on watchOS1 like you, used a UIView and snapshotted it into a UIView. Besides doing this on the phone and sending it back to the watch (in which you loose the benefit of watchOS2 that the extension runs on the watch and doesn't need to communicate with the phone), or getting it as an image from a server, I don't see any other way of doing it.
edit: there is Core Graphics available so we are able to do basic drawings. See here: http://develop.watch/develop-for-watchos-2-iii-drawing/
No. In watch OS 2 you cannot dynamically allocate any UI element. You must use storyboard if you want to init any UI stuff.
Creating an Interface Object
You create interface objects indirectly by adding the object to your
storyboard scene and referring to it from your interface controller.
After adding an element to your storyboard, create an outlet for it in
your interface controller. During the initialization of your interface
controller, WatchKit creates the interface objects for all of your
connected outlets automatically. You never create the interface
objects yourself.

Storyboards in Xcode 6

I have recently started to learn iOS with obj-c from "iOS Programming The Big Nerd Ranch Guide 4th Edition". This edition was released in 2014 and is written with Xcode 5.
I am trying to make a simple app with two buttons and two labels. The labels are connected to two arrays and when a button is pressed an object from the corresponding array is shown in the corresponding text label (it's the Quiz app in chapter 1).
I created the project as a Single View app in Xcode 6, and put all my objects in the view controller class. I have two labels two buttons two arrays and an int to keep track of the object that has to be displayed from the array.
In the book it says that I should initialize the arrays in the initWithNibName method. I tried that but for some reason it never gets called. So I changed the initialization of the arrays to the init method. They initialize fine but when they are called from another method they are nil. Do you have any idea why this is happening?
The second issue I'm having is that I can't manage to get the contents of the storyboard on screen. It says that I'm supposed to make an instance of the ViewController inside the AppDelegate and make it the root window controller but all I get is a white window (or black in case I don't set the color).
UPDATE: I changed the intialization of the arrays from the init method to the viewDidLoad method and now they seem to be working fine. Nothing on the screen though.
It sounds like you're initializing your UIViewController from the app delegate AND a storyboard. If you create a new project in XCode, a "Single view application", you won't have to touch the app delegate at all in order to get something on the screen.
I believe both your problems are related to this, since it sounds like you're seeing an empty UIViewController on the screen (the one you create in the app delegate)
As for the initialization of your array, viewDidLoad is a popular place to do this.
If you are using storyboards, the method initWithNibNameOrNil will not be called. In the BNR book, it teaches you to use XIB files, which do use this method. If you are trying to follow the tutorials, I would suggest using XIB files.
For use of a book, I would suggest downloading whatever version of Xcode is being used for that book -- otherwise you will be running into a lot of confusing problems while learning.
If you would like to download previous version of Xcode, refer to this post:
How to download Xcode DMG or XIP file?

Can I use the default UIBarButton icons provided by Apple in other assets of my app?

Like in UIButton or a UIImageView etc..
If so how do I do that using the StoryBoard or in a Xib
I am able to use the default icons inside UIBarButton items but cannot look them up in normal buttons . A solution using Storyboard would be really nice
In order to use them you need to extract them using a handy little app called (fittingly enough) iOS Artwork Extractor. I use it all the time when I want to mimic iOS system behaviours.
Download the Xcode project at:
https://github.com/0xced/iOS-Artwork-Extractor
Or another way:
The Other.artwork file is in /Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator3.0.sdk/System/Library/Frameworks/UIKit.framework/ (you need the SDK).
Use the "iPhoneShop-1.3.jar" program -- available currently here to extract all of the images into a directory.
java -jar iPhoneShop-1.3.jar ARTWORK Other.artwork EXPORT Other
No you cannot use UIBarButtonItem on other as subview like UIButton. UIBarButtonItem can only over UINavigationBar.

Edit exisiting class propertys or make system wide changes to a class

I have problem with iOS 8 and the SKLabelNode Class.
I used in my Project lot of SKLabelNodes(We speak about 120 nodes) and in iOS8 Apple has changed the built in FontType and now all my Labels hardly readable. I would like to change back, but I dont want to edit all the Nodes by one. I would like to change the SKLabelNode Class Defaults Font type. Is it possible? Or any other solution?
Sounds like your best bet would be to use a category Apple Category Docs
Or take a look at swizzling. There's a good tutorial here Swizzling
I think your best bet is actually method swizzling to replace the getter or modify the category to add a new init that sets a default font. Hope this helps.

How to create a theme based application?

I know similar question is already asked, but didn't get a satisfactory answer. So i am adding this question again .
Based on user selection in iphone application , i need to change the look and feel of the application (color font background images etc ). Is there any standard way to achieve this ?
one possible solution can be duplicating xib files for each theme and loading it based on selection. Is this a good approach? mainly because wiring the outlets and actions for xib copies sounds to be a redundant task.
I would like to see expert suggestion for this doubt.
Thanks for any help in advance.
-mia
For the non-XIB route
Color: iOS 5 exposes the new appearance APIs. Most UI elements have the option if setting a tintColor or a backgroundColor. Rarely, even a background image.
Font: Was always able to change, but you couldn't animate it.
Background image: Your main UIView should have the option for a background image, or if that fails, a background color with a pattern image.
As CodaFI said, if you are using iOS 5 or greater, you already have a theming feature. It works like this:
Add the protocol <IAppearanceContainer> to the class.
Decorate the property you intend to change with UI_APPEARANCE_SELECTOR. Example:
#interface UINavigationBar : ... <IAppearanceContainer>
#property(nonatomic,retain) UIColor *tintColor UI_APPEARANCE_SELECTOR;
#end
Change the color for all instances of the class:
[[UINavigationBar appearance] setTintColor:[UIColor redColor]];
The example above is the UINavigationBar, but it would work with any custom class. To see the objects already supported in iOS 6.1, check the documentation or run the following commands:
cd /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk/System/Library/Frameworks/UIKit.framework/Headers
grep -H UI_APPEARANCE_SELECTOR ./* | sed 's/ __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_5_0) UI_APPEARANCE_SELECTOR;//'
Let's say you want modular themes:
Write a big plist file with all the fonts, colors, music, and what not. Each of these files will be a theme.
Read the file through a singleton and set the values with lines like [x appearance] setWhatever:<plist value>] for each theme-able element.
If you have instances of the same element that need to display different elements, get those images through the singleton.
That is more or less the tip from Amit Vyawahare. I said plist instead xml because they are easier to read. Don't duplicate the NIBs unless you really have to.
Best way to implement theme based application IOS application (not using ~xib route). you should create a build.xml file which will content all the pieces of themes. You should keep your layout same and you can change images, style, fonts, lang, views, in that layout according to users pref. By doing this you are not duplicating any code and you will achieve best performances from your application.

Resources