objective c - What is the right pattern for instantiating a device specific view controller in a Universal App? -
i'm new objective-c so, bear me. started universal app template in xcode4 , built application. there convention template starts off tried stick with. each view controller, there's main file , subclass each device type. example:
project/ exampleviewcontroller.(h|m) - iphone/ - exampleviewcontroller_iphone.(h|m|xib) - ipad/ - exampleviewcontroller_ipad.(h|m|xib) for part, pretty convenient. of logic goes in superclass , subclasses take care of device specific implementation.
here's part don't get. have code same thing in each subclass because need load different xib each device. example:
exampleviewcontroller_iphone
- (void)tableview:(uitableview *)tableview didselectrowatindexpath:(nsindexpath *)indexpath { content *selectedcontent = (content *)[[self fetchedresultscontroller] objectatindexpath:indexpath]; contentdetailviewcontroller_iphone *detailviewcontroller = [[contentdetailviewcontroller_iphone alloc] init]; detailviewcontroller.content = selectedcontent; detailviewcontroller.managedobjectcontext = self.managedobjectcontext; [self.navigationcontroller pushviewcontroller:detailviewcontroller animated:yes]; [detailviewcontroller release]; } exampleviewcontroller_ipad
- (void)tableview:(uitableview *)tableview didselectrowatindexpath:(nsindexpath *)indexpath { content *selectedcontent = (content *)[[self fetchedresultscontroller] objectatindexpath:indexpath]; contentdetailviewcontroller_ipad *detailviewcontroller = [[contentdetailviewcontroller_ipad alloc] init]; detailviewcontroller.content = selectedcontent; detailviewcontroller.managedobjectcontext = self.managedobjectcontext; [self.navigationcontroller pushviewcontroller:detailviewcontroller animated:yes]; [detailviewcontroller release]; } ... notice in second instance thing different it's loading _ipad version of view controller. necessary because ipad , iphone view controllers attached separate, device specifc nibs.
what's "correct" pattern doing this?
update
i found this answer loading separate xibs using device modifiers seems in case don't need specific subclass 1 device, still won't if need instantiate specific _iphone or _ipad instance of view controller device specific functionality.
there 2 simple ways solve problem. both work when placed in superclass.
the first method works because have 2 different classes, , 1 created depends on device being used. does not work if don't use different classes because there no device-specific code. involves asking object class decide is. since object's class device-specific class, when asked superclass, can check see class created , act accordingly.
- (void)tableview:(uitableview *)tableview didselectrowatindexpath:(nsindexpath *)indexpath { content *selectedcontent = (content *)[[self fetchedresultscontroller] objectatindexpath:indexpath]; class classtouse; if([self class] == [exampleviewcontroller_ipad class]) { // running on ipad classtouse = [contentdetailviewcontroller_ipad class]; } else { // must running on either iphone or ipod touch classtouse = [contentdetailviewcontroller_iphone class]; } // use superclass typing here, since aren't doing device specific contentdetailviewcontroller *detailviewcontroller = [[classtouse alloc] init]; detailviewcontroller.content = selectedcontent; detailviewcontroller.managedobjectcontext = self.managedobjectcontext; [self.navigationcontroller pushviewcontroller:detailviewcontroller animated:yes]; [detailviewcontroller release]; } the second method work in location in program. apple added property uidevice class in ios 3.2 called "user interface idiom". there 2 possible values: uiuserinterfaceidiompad , uiuserinterfaceidiomphone. since these don't exist in versions prior 3.2, apple added macro return uiuserinterfaceidiomphone if version less 3.2, , actual value uidevice object if greater or equal 3.2.
- (void)tableview:(uitableview *)tableview didselectrowatindexpath:(nsindexpath *)indexpath { content *selectedcontent = (content *)[[self fetchedresultscontroller] objectatindexpath:indexpath]; class classtouse; // if aren't supporting versions prior 3.2, can use [uidevice currentdevice].userinterfaceidiom instead save couple of cycles if(ui_user_interface_idiom() == uiuserinterfaceidiompad) { // running on ipad classtouse = [contentdetailviewcontroller_ipad class]; } else { // must running on either iphone or ipod touch classtouse = [contentdetailviewcontroller_iphone class]; } // use superclass typing here, since aren't doing device specific contentdetailviewcontroller *detailviewcontroller = [[classtouse alloc] init]; detailviewcontroller.content = selectedcontent; detailviewcontroller.managedobjectcontext = self.managedobjectcontext; [self.navigationcontroller pushviewcontroller:detailviewcontroller animated:yes]; [detailviewcontroller release]; }
Comments
Post a Comment