Styling Custom UITableViewCell Using UIAppearance - ios

I have a custom UITableViewCell and I want to style that using the UIAppearance protocol.
#interface MyCell : UITableViewCell<UIAppearance>
{
}
#property (nonatomic,weak) UIView *backgroundCellView UI_APPEARANCE_SELECTOR;
MyCell.m:
-(void) setBackgroundCellView:(UIView *)backgroundView
{
NSLog(#"setBackgroundCellView");
[super setBackgroundView:backgroundView];
}
In the app delegate I am doing the following:
[[MyCell appearance] setBackgroundCellView:[UIImageView .... with an image]];
It assign the background to few cells but not all the cells. Usually the assigned ones are in the middle.

One cannot assigning the same UIImageView to multiple cells and try to display that. The same UIView cannot be part of only one subview hierarchy.
What needs to be done instead is to make is a custom background view which has a UIImage configurable with UIAppearance.
Basically one should configure the background view's image using UIAppereance and not the background view itself.

Related

Displaying a User Tag with a UILabel and UIButton

In my app, I have a list of tags corresponding to a user that I would like to display. The tag should have a text field and a button on the right hand side to delete the tag (much like the tags on this site when asking a question!)
I only want part of the tag to be clickable, so I don't want to place a UILabel inside a UIButton, and it seems that adding a UIButton to a UILabel is bad practice. What is the best way to create this object?
I want something similar to a UITableViewCell, but not a UITableViewCell because it won't be displayed in a table view.
Just to create a UIView subclass, we could name it TagView, give UILabel and UIButton to display, and don't forget to create a delegate protocol to for action response.
Maybe it like this.
#protocol TagViewDelegate
#optional
- (void)didSelectedTagView:(TagView *)tagView;
- (void)didTagViewAccessoryButtonTapped:(TagView *)tagView;
#end
#interface TagView : UIView
{
UILabel *label;
UIButton *accessoryButton;
}
#property (weak, nonatomic) id delegate;
#property (readonly, nonatomic) UILabel *label;
#end
Then implement a UITapGestureRecognizer for label and touchUpInside event for button
- (void)initUIElement {
// give it a gestureRecognizer for label to response the label did select
UITapGestureRecognizer *labelTapGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(didSelectedLabel:)];
[label addGestureRecognizer:labelTapGR];
[accessoryButton addTarget:self action:#selector(accessoryTapped:) forControlEvents:UIControlEventTouchUpOutside];
}
in the method didSelectedLabel: and accessoryTapped: , give response to tagView's delegate like this.
- (void)didSelectedLabel:(UITapGestureRecognizer *)gestureRecognizer
{
[self.delegate didSelectedTagView:self];
}
- (void)accessoryTapped:(id)sender
{
[self.delegate didTagViewAccessoryButtonTapped:self];
}
There is a library you may take a look.
DWTagList
Just like cabellicar123 said, use a UIView and place your UILabel and UIButton inside it. You have a couple of ways to do this.
First, you can make a XIB file with the main view being your UIView, and just drag into it a UIButton and a UILabel and position them the way you want, and then in code load the nib when you need it.
Second is to create this UIView programmatically, and use the addSubview method and add your UILabel and UIButton that way. Make sure you have defined these two subviews with initWithFrame if you are using this method, so that they are correctly placed WITHIN the UIView. What I mean by this is that the origin of these views should be relative to the top left corner of the UIView.

Change the selected cell background colour using UIAppearance

I need to change the selected cell background colour for all the cells in my app. As I know there is a way to use UIAppearance protocol for this purposes. Is it possible to realize this by the category for UITableViewCell?
Using appearance proxy you can colour all cells. Don't know if you can target specific category.
To do the colouring put following code in your AppDelegate.m file:
Put [self customCellBackground];
in - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions
and somewhere at the end:
- (void)customCellBackground {
UIView *cellBackgroundView =[[UIView alloc] init];
cellBackgroundView.backgroundColor = [UIColor blackColor];
[[UITableViewCell appearance] setSelectedBackgroundView:cellBackgroundView];}
As null's answer is not for selected cell backgrounds and Armands L.'s answer did not work consistently for me (selecting cells by 'user-tap' did work, but programmatical cell selection showed strange results (like sometimes the selected background was not visible, or did not fill the cell's height properly...).
I found a custom solution that worked:
Subclass UITableViewCell
Initialize self.selectedBackgroundView in init and
Add custom UIColor property with UI_APPEARANCE_SELECTOR for custom selected background color
.h file:
#property (nonatomic) UIColor* selectedCellBackgroundColor UI_APPEARANCE_SELECTOR;
.m file:
in init method(s):
self.selectedBackgroundView = [[UIView alloc] init];
and last but not least the setter function for the color:
- (void) setSelectedCellBackgroundColor:(UIColor*) color {
_selectedCellBackgroundColor = color;
self.selectedBackgroundView.backgroundColor = color;
}
You can't do this direct to UITableViewCell, but you can do it for its contentView:
[[UIView appearanceWhenContainedIn:[UITableViewCell class], nil] setBackgroundColor:[UIColor redColor]];
Note that it will change all the subViews bg color.
Another option is writing a category or subclass the UITableViewCell with UI_APPEARANCE_SELECTOR mark, check this question:
iOS: Using UIAppearance to define custom UITableViewCell color

How to set Accessoryview to static UITableViewCell?

I have created a UITableViewController with a UITableView and static UITableViewCells.
How can I change the Accessory View to a custom Image within a UIImageView?
I know how to change the Accessory View generally:
UIImage *accessor = [UIImage imageNamed:#"imageName"];
[somecell setAccessoryView:[[UIImageView alloc] initWithImage: accessor]];
The solution:
Create an IBOutlet for each UITableViewCell which should have a custom accessory view and connect the IBOutlet to the UITableViewCell in the storyboard. After that you can set the accessory view like above.
I found a better solution:
Drag a view (for example a instance of UISwitch) into UITableViewController in storyboard
Selet the cell on which you want to add a custom accessory view. Then open the Connections inspector, drag the accessoryView in section Outlets to the view that you created in step 1.
Now run the app, see a custom accessory view appearing in a static UITableViewCell. Of course you can create another IBOutlet between the UISwitch and controller so that you could get the reference of it, or create an IBAction for receiving action when user change the value of UISwitch.
Add a custom UIButton in the storyboard and set the image you want to it

How to insert a UITextView to a UIImageView

I'm programming an application, in wich you create UIImageView-objects.
The color of these objects can be set.
But the next step I am trying to do is: set a TextView in the imageView, but this text should entered by the user (certainly realized with the class UIKeyboard.)
Im sum: I have a imageView, which needs an editable UITextView in it.
Do you have any idea how it could be realized?
Your approach is wrong.
You want an image view because the app lets you "create an image"
In reality and technically this isn't correct, what you will want to be doing is using a simple UIView to set he colour of an area, and you an place a UITextField or UITextView over that.
A UIImageView is a very specific UIView subclass for displaying images. You can't add your other UI inside of it, the best you could do is over it.
I you do use a UIView, when you're done you need to "convert" your UIView to an image which you can then use to save, send etc
For more about that check out Save UIView's representation to file
You simply want to subclass UIImageView and add a UITextView during init. Like this
#interface MyImageView : UIImageView {
}
#property (nonatomic, strong) UITextView *textView;
#end
And the implementation
#implementation MyImageView
- (id)init {
if ((self = [super init])) {
self.textView = [[UITextView alloc] initWithFrame:CGRectMake(...)];
[self addSubview:self.textView];
}
return self;
}
#end

How to assign my CustomNavigationBar to a UINavigationController?

In order to customize the aspect of the navigationBar of my UINavigationController, I've been told to subclass the UINavigationBar class.
I need to change the height of the bar, placing an image instead of the title.. etc. I can't do it just using UINavigationBar properties.
Now, my issue is, how to assign to the UINavigationController, my CustomNavigationBar instance ? I can't use UINavigationController.navigationBar because it is read-only.
The only way seems to load a xib, but subclassing UINavigationController is not reccomended by Apple, so I'm a bit confused.
Depending exactly on how custom you want the nav bar, the following may help you:
1) An image in the bar, replacing the title text. (self is a UIViewController)
UIImageView *titleImg = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"image.png"]];
self.navigationItem.titleView = titleImg;
[titleImg release];
2) A totally custom nav bar
Subview UIView (CORRECTION: UINavigationController) with a nib, using (for example, of iPhone portrait orientation) a imageview as the background (could have a gradient) and then custom buttons on the left and right side, all hooked up to your relevant responder functions. As long as you add this nav bar view as a subview to each view controller etc each time a new one is pushed to the stack, you would have overriden Apple's standard nav bar. (remember to set theirs to hidden in the app delegate)
Edit:
NavigationBar.h
#interface NavigationBar: UIViewController
{
IBOutlet UIImageView* navigationBarImgView; // remember to set these 4 IBOutlets as properties with (nonatomic, retain) and synthesize them.
IBOutlet UILabel* controllerHeader;
IBOutlet UIButton* rightButton;
IBOutlet UIButton* leftButton;
eController controller;
int screenWidth;
}
NavigationBar.m
-(id)initNavigationBar: (NSString*)name bundle:(NSBundle*)bundle: (eController)controllerName: (int)inScreenWidth
{
[super initWithNibName:name bundle:bundle];
controller = controllerName;
screenWidth = isScreenWidth;
return self;
}
You can see my init here only passes in a few things - an enum which was defined in my app delegate which contains the names of all possible view controllers. We interpret this enum in my custom Navigation Bar class and switch between all the possible controllers, and then setup their buttons and titles and the actions that get fired off using that information. The screen width is important - although you may not need this if you create the bar in IB, set the size of it to fill up the allocated space for both orientations.
Keep me posted :)

Resources