Want to dynamically change UIWebView parent

Asked 2 years ago, Updated 2 years ago, 79 views

The configuration is as follows:

  • parentUIViewController
  • childUIImageView
  • GrandchildUIWebView 複数Multiple

It looks like addSubView with children as background images, and as a result, there are several smaller UIWebView on top of the background images.

When I tap one of my grandchildren, I change the frame of my grandchildren to the full screen size, and I directly addSubView to the parent to change the one that was parent→child→grandchild to parent→grandchild When I was developing it with iOS 7 (or Xcode 4.x to be exact), this worked, but in order to support iOS 8, I corrected the deviation in the xib file and checked it, and when I addSubView my grandson directly to his parents, the target UIWebView disappeared.

If you do addSubView to the parent, it will be displayed properly, so if you do a replacement, it will be released from memory?If you log out the target object immediately after addSubView, it may not be

The UIWebView declared in IBOutlet as property of (nonatomic, retain).

Could someone please lend me some advice?
_<)
Thank you for your cooperation.

--------------
Below is a list of possible relevant codes.
Once the double tap is detected in the GestureWindow, the DoubleTapedWebView of the BaseController is called.

Also, when I tried to meet the requirements by displaying it at the top of the list without replacing it with a parent (without addingSubView), it turned out to be a mysterious move.

  • At initial maximization → hidden behind other grandchildren (bringSubviewToFront is not working?) and the display position is also set to 0,0 for frame position, but it is not moving from its original position
  • Maximizing after the second time → Maximizing as expected

After the second time, I did addSubView in the process of returning from maximization to the original size, so maybe the bringSubviewToFront doesn't work in the first place.
I would appreciate it if you could let me know if anyone can think of this cause.

Thank you for your cooperation.

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;//Grandchild UIWebView property
@synthesize_info;// grandchild UIWebView property
@syntesize_movie; // grandchild UIWebView property
@synthesize_base;// child UIImageView property

- (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);
    UISscreen* screen = [UISscreen mainScreen];
    if([selfisInitBeforeRect]){
        // Original → Maximize
        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];
//        _basebringSubviewToFront:webView; // Try to display it at the top of the child without directly transferring it to the parent
    } else {
        // Maximize → Original
        [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;
    idgDelegate;
    NSTimeInterval lastEventTime;
    NSTimeInterval currentEventTime;
}
@property(nonatomic, retain) idgDelegate;
@property(nonatomic,retain)NSMutableArray*webViewArray;
@property(nonatomic)NSTimeInterval lastEventTime;
@property(nonatomic)NSTimeInterval currentEventTime;

@end
GestureWindow.m
@implementation GestureWindow


@synthesizeDelegate, webViewArray, lastEventTime, currentEventTime;

- (void) sendEvent: (UIEvent*) event {
    currentEventTime=event.timestamp;
    super sendEvent:event;
    NSSet*touches= [event allTouches];
    // No multi-touch
    if(touches.count!=1){  
        return;  
    }

    UITouch* touch = touches.anyObject;
    int tcCnt = [touch tapCount];

    // Exit if it is not a double tap
    if(tcCnt!=2){
        return;
    }
    // Touch the specified UIWebView?
    for (UIWebView* uwin webViewArray) {
        if([touch.view isDescendantOfView:uw]){
            if ((currentEventTime-lastEventTime)<0.7){
                break;
            }
            lastEventTime = currentEventTime;

            gDelegate doubleTapedWebView:uw;
            NSLog (@"calldoubleTapedWebView: %p", uw);
            break;
        }
    }
}
@end

ios ios8

2022-09-30 20:34

2 Answers

I tried using the code below, but it was not reproduced.
Therefore,

Parents → children → grandchildren are replaced like parents → grandchildren.

The behavior seems to have changed for another reason, not for .

@interfaceMainViewController()
@property (weak, nonatomic) Deploy with IBOutlet UIImageView* imageView; //xib
@property(nonatomic,strong)NSMutableArray*webViews;
@end

@implementation MainViewController

- (void) viewDidLoad{
    superviewDidLoad;
    // Do any additional setup after loading the view from its nib.

    // Put the button on the navigation bar for ease of use.
    UIBarButtonItem* action=[UIBarButtonItem.alloc initWithBarButtonSystemItem:UIBarButtonSystemItemAction
                                                                          target —self
                                                                          action:@selector(barAction:);
    self.navigationItem.rightBarButtonItem=action;

    // tile UIWebView on imageView subview
    self.webViews = NSMutableArray array;
    CGFloat width = self.imageView.frame.size.width/4;
    CGFloat currentY = 0.0f;
    while(currentY<self.view.frame.size.height){
        for(inti=0;i<4;++i){
            CGRect frame = CGRectMake (width*i, currentY, width, width);
            UIWebView* webView= [UIWebView.alloc initWithFrame:frame];
            [webView loadRequest: [NSURLRequestRequestWithURL: [NSURLURLWithString:@"https://www.google.co.jp/"]]];
            [self.imageView addSubview:webView]; // Parent (View)->Child (UIImageView)->Grandchild (UIWebView)
            [self.webViews addObject:webView];
        }
        currentY+=width;
    }
}

- (void)barAction: (id) sender
{
    // Parent (View)->Child (UIImageView)->Grandchild (UIWebView) to Parent (UIWebView)->Grandchild (UIWebView)
    UIWebView* webView=self.webViews[0];
    [webView removeFromSuperview;
    webView.frame =self.view.frame;
    [self.view addSubview:webView];
}


2022-09-30 20:34

If I replace it, will it be released from memory?

I'd like to touch on a couple of things about this "free from memory."
Objective-C manages objects (instances) in a way called reference counting.It is the same even if Automatic Reference Counting (ARC) is enabled.Just whether it's automated or not.The instance is not released and retained while it is referenced by other instances.If you are no longer referenced by another instance, or if the instance you are referring to is released and none of it is gone, the instance is released at any time.
For collection classes such as NSAray and NSDictionary, instances that are elements of the collection class are not released while they are elements.This is because the collection class is supposed to refer to an instance of an element.If removed (removeObject:) is not referenced from a collection class, the instance is released at any time.
The UIView has an NSAray-type property called subviews, which Superview manages with the subviews.Therefore, the reference method is the same as that of NSAray.addSubview —Subview in the also preserves the Subview as long as it references and maintains the Superview.When removed from Superview in removeFromSuperview, the original Subview is released at any time if it is not referenced by anyone else.
Based on the above, by following the code and examining the reference relationship of instances that appear to be free of memory, you can find out when to be free of memory.
What I'm a little curious about is that when you pass an instance from one variable to another, are there any parts that are copied instead of passing the reference?This means that the instance immediately after copying has zero references, so if you leave the scope ({~}), you will be free at any time.
It is clear whether it is a reference pass or a copy pass by checking the address of the instance.Remember that instances of Objective-C are handled by pointers.

NSLog(@"Subviews address=%p", targetView);

You can output the address of the instance (pointer) with the symbol %p in this way.It may also be useful to track the View by inserting NSLog() into the code as appropriate.


2022-09-30 20:34

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.