I am in editing mode.
The dark grey is an imageView, that it seems being pushed by the reorder icons, and you can see the UIview in the background (light grey).
I do not like this to happen.
What do you think?
Are you wanting to hide the reorder button and its views? If so, you can override the didTransitionToState method in your custom UITableView like so:
- (void)didTransitionToState:(UITableViewCellStateMask)state
{
//modified from comments here:
//http://www.erasetotheleft.com/post/overriding-the-drag-reorder-control-in-uitableviewcell/
if(state == UITableViewCellStateEditingMask)
{
for (UIControl *control in self.subviews)
{
// Find the Reorder Control
if ([control isMemberOfClass:NSClassFromString(#"UITableViewCellReorderControl")] && [control.subviews count] > 0)
{
// Create Pointer to Reorder Controls Image View
UIImageView *imageView = [control.subviews objectAtIndex:0];
// Set Image Views Hidden Property to NO
imageView.hidden = YES;
}
}
}
}
Related
I'm trying to create a custom keyboard for a UITextField, the background of this inputView should be transparent, I have set the background color in the view's xib file to "clear color". It is working great on iOS 6 and earlier.. but on iOS 7 it not working
Any idea how can I make it work? I want it to be fully transparent
This will set the backdrops opacity to zero when displaying your custom keyboard and reset it back to 1 when the normal keyboard is shown.
+ (void)updateKeyboardBackground {
UIView *peripheralHostView = [[[[[UIApplication sharedApplication] windows] lastObject] subviews] lastObject];
UIView *backdropView;
CustomKeyboard *customKeyboard;
if ([peripheralHostView isKindOfClass:NSClassFromString(#"UIPeripheralHostView")]) {
for (UIView *view in [peripheralHostView subviews]) {
if ([view isKindOfClass:[CustomKeyboard class]]) {
customKeyboard = (CustomKeyboard *)view;
} else if ([view isKindOfClass:NSClassFromString(#"UIKBInputBackdropView")]) {
backdropView = view;
}
}
}
if (customKeyboard && backdropView) {
[[backdropView layer] setOpacity:0];
} else if (backdropView) {
[[backdropView layer] setOpacity:1];
}
}
+ (void)keyboardWillShow {
[self performSelector:#selector(updateKeyboardBackground) withObject:nil afterDelay:0];
}
+ (void)load {
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:#selector(keyboardWillShow) name:UIKeyboardWillShowNotification object:nil];
}
I am chasing the same issue, as I have a numeric keypad which fills only the left half of the screen in landscape mode (and is basically unusable on iOS7 where the blur effect covers the entire width of the screen). I haven't quite figured out how to get what I want (blurred background only behind my actual inputView), but I have figured out how to disable the blur entirely:
Define a custom subclass of UIView and specify that in your xib file
In this class override willMoveToSuperview: as follows
- (void)willMoveToSuperview:(UIView *)newSuperview
{
if (UIDevice.currentDevice.systemVersion.floatValue >= 7 &&
newSuperview != nil)
{
CALayer *layer = newSuperview.layer;
NSArray *subls = layer.sublayers;
CALayer *blurLayer = [subls objectAtIndex:0];
[blurLayer setOpacity:0];
}
}
This appears to impact the background of every custom inputView I have (but not the system keyboard) so you might need to save/restore whatever the normal opacity value is when your inputView gets removed from the superview if you don't want that.
iOS 7 is doing some things under the hood that are not documented. However, you can examine the view hierarchy and adjust the relevant views by overriding -willMoveToSuperview in your custom input view. For instance, this code will make the backdrop transparent:
- (void)willMoveToSuperview:(UIView *)newSuperview {
NSLog(#"will move to superview of class: %# with sibling views: %#", [newSuperview class], newSuperview.subviews);
if ([newSuperview isKindOfClass:NSClassFromString(#"UIPeripheralHostView")]) {
UIView* aSiblingView;
for (aSiblingView in newSuperview.subviews) {
if ([aSiblingView isKindOfClass:NSClassFromString(#"UIKBInputBackdropView")]) {
aSiblingView.alpha = 0.0;
}
}
}
}
If you look closely to the bottom of the UISearchBar in a UISearchDisplayController, you'll notice it has a subtile drop shadow. This shadow doesn't fit in the design of the app I'm currently working on, so I'm trying to remove/hide it. Unfortunately I have not yet succeeded.
During my research into this drop shadow, I found that it's not part of the UISearchBar. When I remove the UISearchDisplayController's UISearchBar from its superview in - (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller, the shadow remains visible.
The shadow turned out to be part of the UISearchDisplayController's searchResultsTableView: when I hide the searchResultsTableView, the shadow disappears. However, I have not been able to trace down the view that has the shadow on its layer. I tried recursively iterating through all visible views (starting at [[UIApplication sharedApplication] window]) and then hiding the drop shadow of each view and setting its clipsToBounds property to YES, which also did not yield the desired result.
Any ideas?
I finally found a solution. Since setting clipsToBounds to YES and hiding the drop shadow of each view in the hierarchy didn't work, it's obvious that the shadow is an image. After iterating through all subviews of the searchResultsTableView and printing their class property, I found an instance of _UISearchBarShadowView, which obviously is the culprit. So what I'm doing now is finding the _UISearchBarShadowView and setting its alpha to 0.0f.
- (void)searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView
{
[self _findAndHideSearchBarShadowInView:tableView];
}
- (void)_findAndHideSearchBarShadowInView:(UIView *)view
{
NSString *usc = #"_";
NSString *sb = #"UISearchBar";
NSString *sv = #"ShadowView";
NSString *s = [[usc stringByAppendingString:sb] stringByAppendingString:sv];
for (UIView *v in view.subviews)
{
if ([v isKindOfClass:NSClassFromString(s)]) {
v.alpha = 0.0f;
}
[self _findAndHideSearchBarShadowInView:v];
}
}
The accepted answer uses a private API, which could get your app rejected. Instead, I'd just locate and hide any subviews that are also custom subclasses of UIImageView, like so:
- (void)searchDisplayController:(UISearchDisplayController *)controller didShowSearchResultsTableView:(UITableView *)tableView
{
for (UIView *view in tableView.subviews) {
if ([view.class isSubclassOfClass:[UIImageView class]]) {
view.alpha = 0.f;
}
}
}
in my view I have a scrollView as subview. The scrollView has another subview called thePDFView. It is for showing a PDF page.
This view has 2 subviews. drawImage is an image loaded from disk above the whole PDF view.
And paintView is the second subview where all the painting and markup is done.
But I only want to add paintView when I press the paint Button.
This works, but when I press it again to stop painting mode and remove the view from superview, the whole screen gets white.
How can I bypass that?
- (id)init
{
...
[self.view addSubview:theScrollView];
[theScrollView addSubview:thePDFView];
drawImage = [UIImage imageWithData:retrievedData];
[thePDFView addSubview:drawImage];
paintView = [[PaintViewController alloc] initWithImage:drawImage andPath:pageString];
}
- (void) togglePainting:(NSNotification *)notif {
if (!painting) {
theScrollView.scrollEnabled = false;
[thePDFView addSubview:paintView.view];
}
else {
theScrollView.scrollEnabled = true;
[thePDFView removeFromSuperview];
}
painting = !painting;
}
[thePDFView removeFromSuperview];
removes the whole view which was inside the scroll view leaving you nothing but the scrollview which does not have any subviews now. Hence your view is white. I think you wanted to remove only paintView.view so it should be [paintView.view removeFromSuperview];
Is there any way that I can get a specific cell to change its style or background image while scrolling the table view?
I want to change the image of a cell which is on top of the visible cells. But only its image is going to be changed the others will stay same, until after scrolling the others come to top of the cells which are shown on the screen. Then the top one's image is going to change this time.
You need to implement scrollViewDidScroll: method of UIScrollViewDelegate in your controller then use visibleCells property of UITableView to get the visible cells of the table.
Something like the following code should work
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
UITableView* tableView;
NSArray* visibleCells;
BOOL first;
tableView = (UITableView*)scrollView;
visibleCells = tableView.visibleCells;
first = YES;
for (UITableViewCell* cell in visibleCells) {
if (first) {
//customize the top cell
first = NO;
}else {
//customize the other visible cells
}
}
}
I have gone through this question that shows the following code:
-(NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath{
return #"Sagar";
}
What if I want a custom image instead of the default red button?
Implement this method in custom cell
- (void)willTransitionToState:(UITableViewCellStateMask)state{
[super willTransitionToState:state];
if ((state & UITableViewCellStateShowingDeleteConfirmationMask) == UITableViewCellStateShowingDeleteConfirmationMask) {
for (UIView *subview in self.subviews) {
if ([NSStringFromClass([subview class]) isEqualToString:#"UITableViewCellDeleteConfirmationControl"]) {
UIImageView *deleteBtn = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 64, 33)];
[deleteBtn setImage:[UIImage imageNamed:#"delete.png"]];
[[subview.subviews objectAtIndex:0] addSubview:deleteBtn];
[deleteBtn release];
}
}
}
}
This is a late reply but I hope someone may find this helpful. So the accepted answer seems sort of complicated for me, and #user1684899's answer only works if you just want to change the look of the delete button. I want to completely change the appearance of the delete button (i.e. its frame, position, etc.), so my solution is to add my own delete button to my custom cell and keep it initially hidden, and only show it when the cell is in edit mode. What's more important, I want to hide iOS's original delete button and support backward compatibility, and here's my trick:
- (void)willTransitionToState:(UITableViewCellStateMask)state
{
[super willTransitionToState:state];
if ((state & UITableViewCellStateShowingDeleteConfirmationMask) == UITableViewCellStateShowingDeleteConfirmationMask)
{
if (!IS_IOS_7){
for (UIView *subview in self.subviews)
{
if ([NSStringFromClass([subview class]) isEqualToString:#"UITableViewCellDeleteConfirmationControl"])
{
// hide original button
[[subview.subviews objectAtIndex:0] setHidden:YES];
// show my custom button
[self.deleteButton setHidden:NO];
}
}
} else {
for (UIView *subview in self.subviews) {
for (UIView *subview2 in subview.subviews) {
if ([NSStringFromClass([subview2 class]) rangeOfString:#"Delete"].location != NSNotFound) {
// hide original button
[subview2 setHidden:YES];
// show my custom button
[self.deleteButton setHidden:NO];
}
}
}
}
} else {
// hide my custom button otherwise
[self.deleteButton setHidden:YES];
}
}
And don't forget to add:
[cell.deleteButton addTarget:self action:#selector(deleteEntryAtIndexPath:) forControlEvents:UIControlEventTouchUpInside];
in cellForRowAtIndexPath, so that you can add any thing you want when your delete button is clicked. Here is my result:
The systemwide standard for the intended list-dive-in action, as you said in the comment on luvieere's answer, would be to use the detail-disclosure (blue circled arrow) cell accessory, not the swipe gesture.
That said, if you still want to use the swipe action for this, there's no way to provide your own button without manually intercepting and completely reimplementing the swipe gesture, like what Tweetie does.
luvieere is right -- if you want that same "delete" metaphor, you want to keep it at the red button that Apple provides. Why change it? Its globally recognizable as the standard for delete buttons.
Although, if you want something like Tweetie, where you completely change the behavior of swiping, you could use something like ABTableViewCell where you just draw in your own view. Make a custom table view, override -touchesBegan:withEvent:, and check for touches. Calculate the delta of the two touches (in touchesMoved:withEvent:) and move your own view around.