0

I have a table view with an image view behind it. I'm trying to figure out how to blur the image behind the table view similar to how it looks when you open control center.

Here is my view:

enter image description here

And here is the code for it:

#import "ToursAndConferencesViewController.h"
#import "RSSChannel.h"
#import "RSSItem.h"
#import "WebViewController.h"
#import "DTCustomColoredAccessory.h"
#import "SVProgressHUD.h"

@implementation ToursAndConferencesViewController
{
    UIActivityIndicatorView *loadingIndicator;
}
@synthesize webViewController;

- (void)viewDidLoad
{
    UIImageView *background = [[UIImageView alloc]init];
    background.image = [UIImage imageNamed:@"plain_app-background.png"];

    self.tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
    [self.tableView setBackgroundView:background];
    self.title = @"Tours & Conferences";

    [[SVProgressHUD appearance]setHudBackgroundColor:[UIColor blackColor]];
    [[SVProgressHUD appearance]setHudForegroundColor:[UIColor whiteColor]];

    [SVProgressHUD showWithStatus:@"Loading"];
    // [SVProgressHUD showWithStatus:@"Loading" maskType:SVProgressHUDMaskTypeGradient];
}

- (void)viewDidDisappear:(BOOL)animated
{
    [SVProgressHUD dismiss];
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
    NSLog(@"%@ found a %@ element", self, elementName);
    if ([elementName isEqual:@"channel"])
    {
        // If the parser saw a channel, create new instance, store in our ivar
        channel = [[RSSChannel alloc]init];

        // Give the channel object a pointer back to ourselves for later
        [channel setParentParserDelegate:self];

        // Set the parser's delegate to the channel object
        [parser setDelegate:channel];
    }
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // return 0;
    NSLog(@"channel items %d", [[channel items]count]);
    return [[channel items]count];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 50;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // return nil;

    UIImageView *image = [[UIImageView alloc]init];
    image.image = [UIImage imageNamed:@"CellImage.png"];

    UIImageView *background = [[UIImageView alloc]init];
    background.image = [UIImage imageNamed:@"plain_app-background.png"];

    UIImageView *highlightedCellImage = [[UIImageView alloc]init];
    highlightedCellImage.image = [UIImage imageNamed:@"HighlightedCellImage"];

    UIColor *kfbBlue = [UIColor colorWithRed:8.0/255.0f green:77.0/255.0f blue:139.0/255.0f alpha:1];
    UIColor *kfbLightBlue = [UIColor colorWithRed:24.0/255.0f green:89.0/255.0f blue:147.0/255.0f alpha:1];

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"];
    if (cell == nil)
    {
        cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"UITableViewCell"];
        cell.textLabel.font=[UIFont systemFontOfSize:16.0];
    }
    RSSItem *item = [[channel items]objectAtIndex:[indexPath row]];

    [[cell textLabel]setText:[item title]];

    NSLog(@"Date: %@", [item date]);

    tableView.backgroundColor = [UIColor clearColor];
    [self.tableView setSeparatorColor:kfbBlue];
    cell.textLabel.backgroundColor = [UIColor clearColor];
    cell.textLabel.highlightedTextColor = kfbBlue;
    cell.textLabel.font = [UIFont fontWithName:@"FranklinGothicStd-ExtraCond" size:20.0];
    cell.textLabel.textColor = kfbLightBlue;
    // cell.backgroundView = image;
    cell.backgroundColor = [UIColor clearColor];
    // cell.selectedBackgroundView = highlightedCellImage;
    tableView.backgroundView = background;

    DTCustomColoredAccessory *accessory = [DTCustomColoredAccessory accessoryWithColor:cell.textLabel.textColor];
    accessory.highlightedColor = kfbBlue;
    cell.accessoryView =accessory;

    return cell;
}

- (void)fetchEntries
{
    // Create a new data container for the stuff that comes back from the service
    xmlData = [[NSMutableData alloc]init];

    // Construct a URL that will ask the service for what you want -
    // note we can concatenate literal strings together on multiple lines in this way - this results in a single NSString instance
    NSURL *url = [NSURL URLWithString:@"http://kyfbnewsroom.com/category/conferences/feed"];

    // Put that URL into an NSURLRequest
    NSURLRequest *req = [NSURLRequest requestWithURL:url];

    // Create a connection that will exchange this request for data from the URL
    connection = [[NSURLConnection alloc]initWithRequest:req delegate:self startImmediately:YES];
}

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];

    if (self)
    {
        [self fetchEntries];
    }

    return self;
}

// This method will be called several times as the data arrives
- (void)connection:(NSURLConnection *)conn didReceiveData:(NSData *)data
{
    // Add the incoming chunk of data to the container we are keeping
    // The data always comes in the correct order
    [xmlData appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)conn
{
    /* We are just checking to make sure we are getting the XML
     NSString *xmlCheck = [[NSString alloc]initWithData:xmlData encoding:NSUTF8StringEncoding];
     NSLog(@"xmlCheck = %@", xmlCheck);*/

    // [loadingIndicator stopAnimating];
    [SVProgressHUD dismiss];

    // Create the parser object with the data received from the web service
    NSXMLParser *parser = [[NSXMLParser alloc]initWithData:xmlData];

    // Give it a delegate - ignore the warning here for now
    [parser setDelegate:self];

    //Tell it to start parsing - the document will be parsed and the delegate of NSXMLParser will get all of its delegate messages sent to it before this line finishes execution - it is blocking
    [parser parse];

    // Get rid of the XML data as we no longer need it
    xmlData = nil;

    // Reload the table.. for now, the table will be empty
    [[self tableView]reloadData];

    NSLog(@"%@\n %@\n %@\n", channel, [channel title], [channel infoString]);
}

- (void)connection:(NSURLConnection *)conn didFailWithError:(NSError *)error
{
    // Release the connection object, we're done with it
    connection = nil;

    // Release the xmlData object, we're done with it
    xmlData = nil;

    [SVProgressHUD dismiss];

    // Grab the description of the error object passed to us
    NSString *errorString = [NSString stringWithFormat:@"Fetch failed: %@", [error localizedDescription]];

    // Create and show an alert view with this error displayed
    UIAlertView *av = [[UIAlertView alloc]initWithTitle:@"Error" message:errorString delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [av show];
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [[webViewController webView]loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]]];

    // Push the web view controller onto the navigation stack - this implicitly creates the web view controller's view the first time through
    // [[self navigationController]pushViewController:webViewController animated:YES];
    [self.navigationController pushViewController:webViewController animated:YES];

    // Grab the selected item
    RSSItem *entry = [[channel items]objectAtIndex:[indexPath row]];

    // Construct a URL with the link string of the item
    NSURL *url = [NSURL URLWithString:[entry link]];

    // Construct a request object with that URL
    NSURLRequest *req = [NSURLRequest requestWithURL:url];

    // Load the request into the web view
    [[webViewController webView]loadRequest:req];
    webViewController.hackyURL = url;

    // Set the title of the web view controller's navigation item
    // [[webViewController navigationItem]setTitle:[entry title]];
}

@end
raginggoat
  • 3,570
  • 10
  • 48
  • 108
  • possible duplicate of [How to apply blur to a UIView?](http://stackoverflow.com/questions/11130923/how-to-apply-blur-to-a-uiview) – Pfitz Jan 14 '14 at 20:54

1 Answers1

3

Set your tableView to [UIColor clearColor];

Then download apple's UIImage+ImageEffects category files that contain helper methods to blur images.

You can follow this tutorial for code samples on image blurring

Here is my final result which is an image behind my tableView:

The image was apple's galaxy image blurred and scaled a bit

Pavan
  • 17,840
  • 8
  • 59
  • 100
  • @Unheilig Yeah i think what made this really special is the masking code I had for the cells for both the top and bottom to make it seem more seamless rather than having obvious UITableView boundary outlines and having my text be clipped abruptly ! That made me cringe before, luckily those days are over. – Pavan Jan 14 '14 at 21:10
  • Great work. The masking code for both top and bottom of the cells can be achieved thru the use of ImageEffects? – Unheilig Jan 14 '14 at 21:14
  • @Unheilig Thanks, and no. For me that's not a nice solution, what happens in a situation where I need to shift my TableView slightly? Or even worse, the background image gets changed based on the user's camera roll? Thats why a programmatic solution is the way forward for a dynamic approach to masking. – Pavan Jan 14 '14 at 21:16
  • I haven't done something like this, but by any chance using CAAnimation or UIViewAnimation call in cellWillAppear: for both top and bottom cells? – Unheilig Jan 14 '14 at 21:19
  • Yes there is that way where you can adjust the opacity of the textColor property, but this will change the text opacity as a whole. If that is enough for you then great, you will have the basic blocks of text changing its opacity as a whole. I didn't want to take any shortcuts when it came to the design aspect, and to be honest the method stated was not enough for me. To truly give the effect of text disappearing from either top or bottom is by having the text itself fade in color, it's just a neater look for me. Notice the the top most label in that menu `Finalise Orders` and ...continued – Pavan Jan 14 '14 at 21:26
  • Continued: observe the gradient fade. Thats the affect i was going for, to create a true masking fade in and fade out. It starts from around the region of where the `Products` label is going to the top to clear. same for the bottom – Pavan Jan 14 '14 at 21:27
  • What you did there _is_ nice. And where is the like it button? oh we are on SO. ;-) – Unheilig Jan 14 '14 at 21:30
  • Cheers, and aha if you want to `like` my stuff you can go on my ig ;) LOL – Pavan Jan 14 '14 at 21:31
  • oh right, you have it? Lol the jokes on me then. It's Pavan89 mate. Enjoy the ig! It's not programming related but more fun related from when I'm away from the office! – Pavan Jan 14 '14 at 21:33