Store additional associated infomation in a UIView

2020-02-06 02:07发布

问题:

I've been reading up a lot about Gesture Recognizers on SO - and have managed to write a working code which when a long-press is recognised on an UIImage, an action sheet appears:

{ ...
 UILongPressGestureRecognizer *longPressWall = [[[UILongPressGestureRecognizer alloc]
                                                               initWithTarget:self     action:@selector(deleteImage:)] autorelease];
                     longPressWall.minimumPressDuration = 0.4;
                     l.userInteractionEnabled=YES;
                     [l addGestureRecognizer:longPressWall];
... }


-(void)deleteImage:(UILongPressGestureRecognizer*)sender { 
    if(UIGestureRecognizerStateBegan == sender.state) {
        UIActionSheet *as = [[UIActionSheet alloc] initWithTitle:@"" delegate:self cancelButtonTitle:@"Close" destructiveButtonTitle:@"Delete Screenshot" otherButtonTitles: nil];
        [as showInView:masterView];
        [as release];
    }
}

So, sending information to the Selector deleteImage: is a little tricky in this situation. I want to send a HTTP request to a server when deleteImage is called, so I need some information from the view.

Is there anyway to store information into the UIImageView and retrieve it from sender.view.myinfo (for example) ?

Thanks!

回答1:

The obvious way is to use the tag property. If you need more info you can always subclass the UIImageView and add an extra property.



回答2:

Via an extension you can add a property to UIView to store your associated values, like this:

import Foundation
import ObjectiveC

extension UIImageView
{
    struct Static {
        static var key = "key"
    }
    var myInfo:AnyObject? {
        get { 
            return objc_getAssociatedObject( self, &Static.key ) as AnyObject? 
        }
        set { 
            objc_setAssociatedObject( self, &Static.key,  newValue, .OBJC_ASSOCIATION_RETAIN) 
        }
    }
}

Now you can do this anywhere in your code

let anImageView = UIView()

// set your new property on any UIView:
anImageView.myInfo = <some object>

// get your proeprty from any UIView
myImage = anImageView.myInfo

previous answer (same code, but in Objective-C) Check out objc_setAssociatedObject() in <objc/runtime.h>

I would implement this as a category.. (ARC-style)

#import <objc/runtime.h>

@interface UIImageView (MyInfo)
@property ( nonatomic, strong ) id myInfo ;
@end

@implementation UIImageView (MyInfo)

-(void)setMyInfo:(id)info
{
    objc_setAssociatedObject( self, "_myInfo", info, OBJC_ASSOCIATION_RETAIN_NONATOMIC ) ;
}

-(id)myInfo
{
   return objc_getAssociatedObject( self, "_myInfo" ) ;
}

@end

Now you can do this:

UIImage * myImage ;
myImage.myInfo = <some object>


回答3:

If you wish to store a string in your UIImageView (or any UIView for that matter), try the following-

Set the accessibility identifier in your view, "l"

{
    l.accessibilityIdentifier = @"your string here";
}

Get the UIView, "l," from your gesture recognizer:

-(void)deleteImage:(UILongPressGestureRecognizer*)sender { 
    if(UIGestureRecognizerStateBegan == sender.state) {

    UIView *view = sender.view;
    NSString *storedString = view.accessibilityIdentifier;

    }
}

storedString is the string stored in your UIView. Hope this helps anyone in the future!



回答4:

No, you cannot keep info into an imageView instance. Even if you find writable string property of imageView, this will be a wrong approach. Do this instead: assign an order number to imegeview.tag property, and keep an NSMutableDictionary for the info, thus, the imageView.tag you will use as the key, and the info will be the value.