How do I properly use the identifier property? - ios

I want my program to be like this
if ([UIImageViewObject identifier]==#"heyItsMeYeaCoolDude")
{
do some methods
}
Whenever I do this though my programs crashes saying:
2012-07-29 19:09:58.401 Bridges[2711:f803] -[UIImageView identifier]: unrecognized selector sent to instance 0x8874f70
With a bunch of crap after it.
In my storyboard, I typed heyItsMeYeaCoolDude under label in the identity inspector, and now my program is complaining.
I know I could use tags also, but I'm already using my images tag for something else, help!

In response to the suggestion you made in the comment below your question, #ownageGuy, an answer to the question you pose:
You're welcome to subclass anything you like. Subclassing UIImageView is a perfectly acceptable solution to this problem. You might also consider the container pattern; ie. create a class which contains an instance of a UIImageView and an NSString for the identifier. Then even if there did happen to be a detriment to subclassing UIImageView, as you fear, it would be eliminated.
#interface UIImageViewContainer : NSObject
{
UIImageView* imgView;
NSString* identifier;
}
Then you create an object of type UIImageViewContainer, set imgView to the appropriate UIImageView, and store the identifier string inside identifier.

Related

Creating a UIImageView inside a custom UITableViewCell Class (Swift)

No matter how I seem to attempt to conquer this beast, it always beats me down. I cannot (without errors) have a UIImageView inside my UITableViewCell class. I've tried connecting it from the storyboard to the code through a referencing outlet with a strong and a weak storage, writing out the code myself, and even doing without the storyboard and creating a UIImageView programmatically. Is this just a bug with Swift? Am I doing something wrong?
Here's a screenshot of my error:
The UITableViewCell class already has a property by the name of imageView. This is why you cannot create another property with the same name.
Try using the already available image view or create an UIImageView instance with a different variable name.
Check the UITableViewCell documentation for more information
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewCell_Class/#//apple_ref/occ/instp/UITableViewCell/imageView
It is not a bug in swift and yes you are doing something wrong. A UITableViewCell class already has certain objects in it which can not be overridden. One of those is imageView. Since the base class of UITableViewCell already has an imageView object you are getting an error since you named your object the same thing. Just change the name to something else that is not part of the base class and it will work. Same thing goes for textLabel, detailTextLabel...etc.

Extending a method applicable to all UIButtons

I have a UIButton object in my program.
I want to use it like follows
myButton.setImage:blablabla
mybutton.title:.......blabla
...
...
myButton.placeTextBelowImageWithSpacing:12
While calling my method "placeTextBelowImageWithSpacing:12" it must set the image and text accordingly. I have the method ready with me. How can i use it in the above way.
PS: I hate subclassing.
Thanks in Advance
Create a custom subclass of UIButton. I created a button called FinderButton that has an image and a title centered below it. It works great.
If you hate subclassing then you might want to think about a different line of work.
Being an Objective C programmer that hates subclassing is a bit like being a surgeon who hates blood or a farmer who hates dirt. Defining a class hierarchy is one of the main tools for doing development in an OO language like Objective-C.
You can do this by creating a UIButton category:
UIButton+MyCustomMethod.h
#interface UIButton (MyCustomMethod)
- (void)placeTextBelowImageWithSpacing;
#end
UIButton+MyCustomMethod.m
#implementation UIButton (MyCustomMethod)
- (void)placeTextBelowImageWithSpacing
{
// ...
}
#end
You can't. That isn't valid syntax in Objective-C. The closest you can get to that would be to explicitly declare new properties on UIButton that followed your naming convention. Using them would then look like:
myButton.setTitle = #"something"
Then you could override setTitle's setter (setSetTitle:), and making it call setTitle:forControlState:, which I'm assuming is your goal.
But this should only be done through subclassing (learn to love it, it's a big part of OOP), although if you really really want to, you can add the properties in a category using the Objective-C runtime objc_setAssociatedObject() function more info here: Objective-C: Property / instance variable in category

Possible to link .xib to class written within a class?

I like to keep my code clean and I have multiple classes written for custom cells right now. Most of those cells are used in only 1 UITableView.
So lets say we have the classes CustomUITableViewController and CustomUITableViewCell. What I'm looking for is something along these lines in the CustomUITableViewController.
#interface CustomUITableViewController()
//stuff
#end
#interface CustomUITableViewCell : UITableViewCell
//stuff
#end
#implementation CustomUITableViewCell
//stuff
#end
#implemention CustomUITableViewController
-(UITableViewCell*)cellForRowAtIndexPath... {
CustomUITableViewCell *cell = dequeueCellFor...
return cell;
}
-(void)viewDidLoad {
[super viewDidLoad]
//this next line should be right?????
[self.tableView registerNib:nib forCellReuseIdentifier:#"CustomCell"];
}
#end
Is my viewDidLoad method correct? I should write it just like I would if I was writing the UITableViewCell in a separate file?
What do I put in the .xib file? When I try to change the class to a custom class it doesn't link up with CustomUITableViewCell, and of course it doesn't match up with CustomUITableViewController (although I tried anyways.)
Yes.
What do you mean by 'doesn't link up with CustomUITableViewCell'? As long as your nib object is the nib for your custom cell, and in the xib for that cell the root object is a UITableViewCell with its custom class property set to your CustomUITableViewCell type you should be good to go. I've used this approach myself, although I've found that putting logic in the cells is more pain than it's worth.
On a side note, you should be sure to use a three letter prefix with all your classes to avoid collisions with Apple private classes.
The "Not KVC compliant" error is usually caused by one of two things in this situation:
1) You modified the XIBs but Xcode didn't notice the change and so didn't deploy the modified file. This usually occurs when you change something like the cell identifier in the XIB. Delete your app from the simulator/device and try running again.
2) You had properties declared on the custom class for the cell (or possibly something else unrelated in the view hierarchy) that were connected in IB at one time, but you've since changed the class behind IB's back and it doesn't know that it shouldn't try to make those connections again. Right-click each view in the scene to look for any broken connections and remove them. This happens to me if I correct the spelling of a property or change it in any way and don't remove and re-add the connection in IB. 95% of the time, this is the problem when I see that error.

Subclassing UICollectionViewLayoutAttributes

I recently started playing with the awesome UICollectionView API, making reasonable progress, but have been stuck for almost all day with an issue I'm hoping someone can help me with:
I need to add some custom details to certain cells' attributes.
In order to do this, the right approach seem to be to subclass UICollectionViewLayoutAttributes and add the properties I need to my subclass. So far so good, except that when I return my LayoutAttributesSubclass, I always get the, somehow obscure, following error:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** setObjectForKey: key cannot be nil'
Having tried to track this down for a while, I'm under the impression that the error is related to representedElementKind and representedElementCategory being nil in my subclass's instance. But those properties are read only, so I can't set those.
I've managed to somehow bypass the error by cheating, getting a regular UICollectionViewAttributes instance, then changing it to a LayoutAttributesSubclass using object_setClass, but this then raises a ton of other issues, plus seems rather shady to me.
In short, does anyone knows what the error above means, and how to correctly create/use UICollectionViewLayoutAttributes subclasses?
When setting up custom attributes, you need to subclass UICollectionViewLayoutAttributes and subclass UICollectionViewLayout and "declare" your custom attribute subclass class name by overriding +(Class)layoutAttributesClass in your UICollectionViewLayout class. The system calls this class method to see if there is a custom class to be supplied when you use the factory method for instantiating/dequeuing layout attribute objects.
#interface YourCustomCollectionViewAttributes : UICollectionViewLayoutAttributes
#property (nonatomic) UIEdgeInsets myCustomProperty
#end
#interface YourCustomCollectionViewLayout : UICollectionViewLayout
#end
#implementation YourCustomCollectionViewLayout
+ (Class)layoutAttributesClass
{
return [IRTableCollectionViewLayoutAttributes class];
}
#end
This is correct according to the documentation and should prevent the particular error you are having. Also when you implement custom iVars, be sure to implement an override for -(id)copyWithZone: or the UICollectionView will lose any custom values you have applied to your custom collection view object.

Writing an own iPad photogallery - dealloc error

i want to write my own photogallery like the original "Photos.app" from apple.
I´ve created a UITabbarcontroller in the AppDelegate and then an "ImageViewController" and a "VideoViewController".
In the "ImageViewController" i´ve added an UIScrollView and then made an instance of my own "PhotoGallery" with different properties like imagePerRow, images, paddings etc.
For the "PhotoGallery" i´ve created a new objective-c class as a subclass of "NSObject", where i´m positioning all the different images as UIButtons.
Then i´ve added another function which describes the arrangement for all the images when the device orientation has changed. And the dealloc-function. Thats all.
This class works great, also the rearrangement when the device orientation has changed. The problem is, if i simulate a memory warning in the ios-simulator, the first time the PhotoGallery gets correctly dealloc but if i simulate a warning again, i get a error-message: "[PhotoGallery release]: message sent to deallocated instance ".
I thought its because of the subclass as NSObject, right?
Then i´ve tested it as a UIView. With the same error. So know i don´t know what to do anymore. Hope you understand what´s the problem and you would give me some hints on that..
Think about calling the init-function again? How? Need "drawRect"? I´ve no idea.
Thanks for your time and help,
G.
You're probably not setting the property which holds a reference to the PhotoGallery to nil.
ie. You're keeping a reference to a deallocated instance, and attempting to call release on it.
bad example:
- (void) didReceiveMemoryWarning
{
[photoGallery release];
}
safe(r) example:
- (void) didReceiveMemoryWarning
{
[photoGallery release];
photoGallery = nil;
// or combine both actions if your property attributes are set up to accommodate it:
// self.photoGallery = nil;
}
In the bad example, photoGallery still holds a reference to a now-deallocated instance, and the second memory warning will attempt to send a message to it.
In the safe(r) example, photoGallery is nil, and sending a message to nil is safe.

Resources