Turn from http://onevcat.com/2014/11/watch-kit/find a very good person to write, turn around and continue to follow
Main class Wkinterfacecontroller and life cycle
WKInterfaceControllerIs the same as in WatchKit, and itUIViewControllerwill be the class that takes the most time to develop Watch apps. EachWKInterfaceControlleror its subclasses should correspond to an entire screen of content on the watch. However, it is necessary to remember that the entire watchkit is independent of the UIKit andWKInterfaceControlleris a class that inherits directly from itNSObject, and does not have theUIKitUIResponsersame responsiveness and complete callbacks as in the user interaction.
It is not only relativelyUIViewControllersimple in function, but also greatly simplified in the life cycle.WKInterfaceControllerThere are three life-cycle methods that must be called for each object, respectively, when the object is initialized, when it-initWithContext:will be rendered,-willActivateand after the rendering is finished-didDeactivate. The same analogyUIViewControllercan be understood as a separate correspondence-viewDidLoad,viewWillAppear:as well-viewDidDisappear:. Although you might think of the method name and the actual use of the method that you would consider-initWithContext:appropriateUIViewControllerinitorinitWithCoder:such, but in fact in the-initWithContext:timeWKInterfaceControllerof the "view element" (Please note here I added the quotation marks, because they are not real views, will later Again, it is already initialized and available, which is actually-viewDidLoadmore similar to the behavior in.
We typically-initWithContext:configure the-willActivateproperties of the "view element" in and, and-didDeactivatedeactivateNSTimerobjects like those that holdselfon in. It is important to note that-didDeactivatesetting the view element property in is not valid because the current isWKInterfaceControllerinactive.
Wkinterfaceobject and its sub-categories
WKInterfaceObjectResponsible for the specific interface element settings, including, likeWKInterfaceButton,WKInterfaceLabelor such objects, which is theWKInterfaceImage"view element" we mentioned above. It is possible to start with an illusion and feel that itWKInterfaceObjectshould correspondUIView, but that is not the case.WKInterfaceObjectjust watchkit The actual view of an agent on the Watch Extension side, not the view itself. The view actually displayed and rendered on the screen in the Watch App is not directly visible to the code, and we can only set the property in Extension target with the corresponding proxy object, and then the new WatchKit will be used by the runtime when each run loop needs to refresh the UI. The property value is passed from the phone to the watch App in the wristwatch and the interface refreshes.
In turn, the actual view in the watch wants to pass the user interaction event to the iPhone and needs to beWKInterfaceObjectdone through an agent. Each interoperableWKInterfaceObjectsubclass corresponds to an action, such as a button corresponding to a click event, a switch corresponding to the state of on or off, and a slider corresponding to a floating point value indicating the selected value and so on. It is also very simple to correlate these events, and the corresponding events can be generated directly from the Ctrl-StoryBoard file in the implementation. Although UI resource files and code implementations are in different target, collaboration in Xcode has been seamless.
The Watch app has a completely different layout than the IOS app. You cannot freely specify the specific coordinates of a particular view, nor can you use a flexible interface layout scheme such as AutoLayout or Size Classes. The layout possibilities and flexibility provided by WatchKit are relatively small, and you can only use group to make a "column" layout at the same time as the basic unit of "Rows". This brings a relatively simple layout implementation and, of course, a challenge to the design of interface interaction.
It is also worth mentioning that with the advent of WatchKit and the development of a change in the way the code to write UI or use StoryBoard this debate for many years can be a temporary issue. There is no way to use code for Watch development. First of all, allWKInterfaceObjectobjects must be designed to be added via StoryBoard, and at runtime we can no longer add or remove elements to the interface (if there is a need to remove it, use hidden),WKInterfaceObjectand then some of the layout-related properties, such as the row height row number, Not be able to make changes and settings at run time. Basically at run time we can only change the contents of the view, and by hiding some view elements to achieve a limited change of layout (other view elements will try to fill the hidden elements).
Table and Context Menu
MostWKInterfaceObjectsubclasses are straightforward, but there are two that I would like to say separately, and that isWKInterfaceTableWKInterfaceMenu.UITableViewEveryone is familiar with, although the WatchKitWKInterfaceTableis also used to display a set of data, but because of the characteristics of the WatchKit API data transmission, the use of the photogenicUITableViewis much different and simplified. First, there is no DataSource and Delegate, theWKInterfaceTableamount of data that needs to be rendered is set directly by its instance method-setNumberOfRows:withRowType:. After setting, use the-rowControllerAtIndex:enumerationrowControllerto set all the settings. HererowControlleris the equivalent of what is set in the StoryBoardUITableViewCell, but as with the otherWKInterfaceObject, it is directly inherited fromNSObject. You can complete the display of the table by customizingrowControllerand connecting the elements of the StoryBoard androwControllersetting them. The code is probably like this:
//Myrowcontroller.swiftImport Foundation Import WatchKitclassMyrowcontroller:nsobject {@IBOutlet weak var label:wkinterfacelabel!}//Interfacecontroller.swiftImport WatchKit Import FoundationclassInterfacecontroller:wkinterfacecontroller {@IBOutlet weak var table:wkinterfacetable!Let data= ["Index 0","Index 1","Index 2"] OverrideInit (context:anyobject?) { //Initialize variables here.super.init (Context:context)//Configure interface objects here.NSLog ("%@ Init", self)//Note that you need to set the Myrowcontrollertype in StoryBoard//reuse ID similar to cellTable.setnumberofrows (Data.count, Withrowtype:"Myrowcontrollertype") for(I, value)inchEnumerate (data) {ifLet Rowcontroller = Table.rowcontrolleratindex (i) as?Myrowcontroller {rowController.label.setText (value) }}}}
For a click event, there is no actual delegate present, but similar to the otherWKInterfaceObjectway the action will click which row is sent back for processing as a parameterWKInterfaceController.
Another interesting is the Context Menu, which is a unique interaction with watchkit and does not exist in IOS. In eitherWKInterfaceControllerinterface, press and hold the watch screen, and ifWKInterfaceControllerthere is a context menu present, try to call out to find the corresponding page. This menu can provide up to four buttons to ask the user for action against the current environment. Because the watch screen is limited, it is very unrealistic to put some interactive buttons at the same time as the information is displayed. While the context menu solves this problem well, it is believed that long-press the outbound interactive menu will be a standard interaction for Watch apps in the future.
Adding a Context menu is very simple, add a menu to the StoryBoard,WKInterfaceControllerand add the corresponding MenuItem to the menu.WKInterfaceControllerwe also have a corresponding API to add MenuItem at runtime based on the context (which is one of the few methods that allows us to add elements at run time).
-addMenuItemWithItemIcon:title:action:-addMenuItemWithImageNamed:title:action:-addMenuItemWithImage:title:action:-clearAllMenuItems
But the Menu and MenuItem correspond to the classWKInterfaceMenuandWKInterfaceMenuItemwe have no way to get it. Yes, they don't even exist in the document:(
Basic navigation
WKInterfaceControllerThe built-in navigation relationship is basically divided into three categories. The first is like theUINavigationControllercontrol of a stack-like navigation mode. The associated API has-pushControllerWithName:context:,-popControlleras well-popToRootController. The latter two I don't want to explain too much, for the first method, we need to use the string of the target controllerIdentifier(no you can only set it in StoryBoard) to create it.contextparameters are also passed to the target controller-initWithContext:, so you can use this to pass data in the controller.
The other is the modal form that we are all familiar with, and the corresponding API is-presentControllerWithName:context:-dismissController. For this kind of navigation, andUIKitthe difference is that in the target controller will default in the upper left corner plus a Cancel button, click will directly close the present controller. I just want to say that Apple has finally figured out that every controller that modal out is the fact that it needs to be closed ...
The last type of navigation is similarUIPageControllerto pager navigation. In the IOS app, this kind of navigation is very common in the teaching module of the first start of the app, and can be said to flourish in WatchKit. In fact, I personally think that this will be the most consistent use of WatchKit in the navigation mode. Page navigation on WatchKit may correspond to the functionality provided by the TAB navigation of the IOS app.
In the implementation, page navigation needs to be segue in StoryBoard to connect the different page, the newly addednext pagesegue is to do this:
In addition, another API that modal navigation-presentControllerWithNames:contexts:accepts a numbernamesofcontextmodal, and in this way the number of multiple controllers that are paged out will also be rendered as page navigation.
Of course, as the classic use of StoryBoard, modal and push navigation can also be implemented in StoryBoard through segue. WatchKit also provides the necessary APIs for the segue approach.
Some interface practices
Because the entire architectureUIKitis completely different, many of the previous practices cannot be moved directly into the WatchKit App.
Image processing
In theUIKitwe display the picture generally usedUIImageView, and thenimageset a created object for its propertiesUIImage. For WatchKit, the best practice is to store the image in the Watch App's target (that is, the target of StoryBoard) andWKInterfaceImageuse it as much as possible when setting up the image-setImageNamed:. This method will only pass the image name through the phone to the watch, and then by the watch in its own bundle to find pictures and load, is the quickest way. Note that our code is running on different devices of the watch App, although we can alsoUIImagebuild the object by the relevant method,UIImageand then use-setImage:or-setImageData:to set the picture on the watch, but then we need to put the picture in Extensi On target, and the image's data needs to be transmitted via Bluetooth to the watch, which in general can cause noticeable delays that can affect the experience.
If for some cases, we can only get pictures in Extension target (such as from the network download or code dynamic generation, etc.), and need to reuse, it is best to useWKInterfaceDevicethe-addCachedImage:name:method to cache it into the watch. This way, when we use the image later, we can-setImageNamed:quickly generate and use it from the watch. The cache size for each app is approximately 20M, and WatchKit will be removed from the oldest data to make room for new data.
Animation
Because of the inability to get actual view elements, onlyWKInterfaceObjectsuch proxy objects, and the constraints of the layout system, complex animations, especiallyUIViewseries orCALayerseries of animations, are not possible. The only thing that seems possible now is frame animation, whichWKInterfaceImagecan be achieved by setting up an image with more than one image, or replacing an image with a timer timing. While Apple's own example has been animated in this way, the storage and power consumption of the device can be challenging, and it needs to be tested and observed after actually getting the device.
Use of other Cocoa Touch frameworks
Apple recommends that you do not use features that require prompt user consent, such as corelocation targeting. Because the actual code is running on the phone, this kind of license will also pop up on the phone, but the user is not necessarily just looking at the phone, so it is likely to cause the experience to fall. In addition, most of the background run permissions are not recommended.
For these data and permissions, Apple recommends doing so in the IOS app and sharing data through app Groups to get it in Watch Extension.
Apple Watch App Development 2