UIWebView の親を動的に変更したい
構成としては、
- 親
UIViewController
- 子
UIImageView
- 孫
UIWebView
※複数
のような作りで、子を背景画像として、子に孫を複数 addSubView
して、結果として小さい UIWebView
が背景画像の上にいくつか乗っているような見た目となっています。
孫のいずれかをタップした際に、孫を全画面表示させたい為、タップされた孫の frame を全画面サイズに変更し、親に直接 addSubView
して 親→子→孫 だったものを 親→孫 のように付け替えています。 iOS7 まで (正確には Xcode 4.x ) で開発していた際にはこれで上手くいっていたのですが、iOS8 に対応させる為に、 Xcode 6 にて表示のズレを xib ファイルで修正して動作確認したところ、孫を直接親に addSubView
するタイミングで対象の UIWebView
が表示されず、消えてしまうようになりました。
親に対して、新規でインスタンスを作った別の UIWebView
を addSubView
するとちゃんと表示されるので、付け替えを行うとメモリから解放されてしまったりしているのでしょうか?? addSubView
の直後に対象オブジェクトをログ出力してみると nil
とはなっていないので解放されてるわけではないのでしょうか・・・
対象の UIWebView
は IBOutlet
で (nonatomic, retain)
の property
として宣言しています。
どなたかお知恵をお貸し頂けませんでしょうか (>_<)
宜しくお願い致します。
-----追記-----
関連のありそうな箇所のコードを以下に載せます。
GestureWindow でダブルタップを検知したら BaseController の doubleTapedWebView を呼び出す作りとなっております。
又、親への付け替えをせずに( addSubView をせずに)、この中で一番上に表示させる事で要件を満たそうと試みたところ、不可解な動きとなりました。
- 初回の最大化時→他の孫の後ろに隠れた状態( bringSubviewToFront が効いていない?)で、表示位置も frame の position に0,0を指定しているにも関わらず元の位置から動いていない
- 2回目以降の最大化時→一番上に表示され期待通り最大化表示となる
2回目以降には一度最大化からオリジナルサイズへ戻す処理の中で addSubView しているのでそもそも bringSubviewToFront が効いていないという事なのかもしれませんが。。
こちらの原因も思い当たる方がいらっしゃればお教え頂けると助かります。
宜しくお願い致します。
BaseController.h
#import
#import "ThumbnailImageView.h"
#import "MainImageView.h"
#import "GestureWindow.h"
#import "GDataXMLNode.h"
@interface UIWebView (privateAPI)
- (NSString *)recursiveDescription;
@end
@interface BaseController : UIViewController
{
IBOutlet UIImageView* _base;
IBOutlet UIWebView* _info;
IBOutlet UIWebView* _corp;
IBOutlet UIWebView* _movie;
}
@property (nonatomic, retain) IBOutlet UIWebView *_info;
@property (nonatomic, retain) IBOutlet UIWebView *_corp;
@property (nonatomic, retain) IBOutlet UIWebView *_movie;
@property (nonatomic, retain) IBOutlet UIImageView *_base;
@end
BaseController.m
#import "BaseController.h"
#import "UIImage+Extras.h"
#import "ThumbnailImageView.h"
#import "GestureWindow.h"
#import
#import "NSBundle+MyStrings.h"
@interface BaseController ()
@end
@implementation BaseController
@synthesize _corp;//孫のUIWebViewプロパティ
@synthesize _info;//孫のUIWebViewプロパティ
@synthesize _movie;//孫のUIWebViewプロパティ
@synthesize _base;//子のUIImageViewプロパティ
- (void)viewDidLoad
{
gWindow = (GestureWindow*)[[UIApplication sharedApplication].windows
objectAtIndex:0];
gWindow.gDelegate = self;
NSMutableArray* webArray = [NSMutableArray array];
[webArray addObject:_info];
[webArray addObject:_corp];
[webArray addObject:_movie];
gWindow.webViewArray = webArray;
}
-(void) doubleTapedWebView:(UIWebView *)webView
{
NSLog(@"doubleTapedWebView start:%p",webView);
UIScreen *screen = [UIScreen mainScreen];
if([self isInitBeforeRect]){
//オリジナル→最大化
beforeRect = webView.frame;
[webView.scrollView setZoomScale:maxScale animated:YES];
webView.frame = CGRectMake(
0
,0
,screen.bounds.size.width
,screen.bounds.size.height
);
[webView.layer setCornerRadius:0];
[self.view addSubview:webView];
// [_base bringSubviewToFront:webView];//試しに親への直接付け替えをせずに子の中で一番上に表示させる
}else{
//最大化→オリジナル
[webView.layer setCornerRadius:10];
isAutoZoomed = NO;
[webView.scrollView setZoomScale:minScale animated:YES];
webView.frame = beforeRect;
[self initBeforeRect];
[_base addSubview:webView];
}
}
@end
GestureWindow.h
@protocol GestureWindowDelegate
- (void) doubleTapedWebView:(UIWebView*)webView;
@end
#import
@interface GestureWindow : UIWindow{
NSMutableArray* webViewArray;
id gDelegate;
NSTimeInterval lastEventTime;
NSTimeInterval currentEventTime;
}
@property (nonatomic, retain) id gDelegate;
@property (nonatomic, retain) NSMutableArray* webViewArray;
@property (nonatomic) NSTimeInterval lastEventTime;
@property (nonatomic) NSTimeInterval currentEventTime;
@end
GestureWindow.m
@implementation GestureWindow
@synthesize gDelegate,webViewArray,lastEventTime,currentEventTime;
- (void)sendEvent:(UIEvent *)event {
currentEventTime = event.timestamp;
[super sendEvent:event];
NSSet *touches = [event allTouches];
//マルチタッチは禁止
if (touches.count != 1) {
return;
}
UITouch *touch = touches.anyObject;
int tcCnt = [touch tapCount];
//ダブルタップでない場合は終了
if(tcCnt !=2){
return;
}
// 指定のUIWebViewへのタッチか
for(UIWebView *uw in webViewArray){
if([touch.view isDescendantOfView:uw]){
if((currentEventTime - lastEventTime) < 0.7){
break;
}
lastEventTime = currentEventTime;
[gDelegate doubleTapedWebView:uw];
NSLog(@"call doubleTapedWebView:%p",uw);
break;
}
}
}
@end