Update App Update screen to be more iOS 6 like

Also do some small refactoring and rename the PS classes to BIT to avoid any possible namespacing problems
This commit is contained in:
Andreas Linde 2012-10-21 00:38:12 +02:00
parent 11a708d446
commit 857d02347e
14 changed files with 545 additions and 529 deletions

View File

@ -0,0 +1,41 @@
/*
* Author: Andreas Linde <mail@andreaslinde.de>
* Peter Steinberger
*
* Copyright (c) 2012 HockeyApp, Bit Stadium GmbH.
* Copyright (c) 2011-2012 Peter Steinberger.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#import <UIKit/UIKit.h>
@interface BITAppStoreHeader : UIView
@property (nonatomic, copy) NSString *headerLabel;
@property (nonatomic, copy) NSString *middleHeaderLabel;
@property (nonatomic, copy) NSString *subHeaderLabel;
@property (nonatomic, retain) UIImage *iconImage;
@end

161
Classes/BITAppStoreHeader.m Normal file
View File

@ -0,0 +1,161 @@
/*
* Author: Andreas Linde <mail@andreaslinde.de>
* Peter Steinberger
*
* Copyright (c) 2012 HockeyApp, Bit Stadium GmbH.
* Copyright (c) 2011-2012 Peter Steinberger.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#import "BITAppStoreHeader.h"
#import "BITHockeyHelper.h"
#import "HockeySDKPrivate.h"
#define BIT_RGBCOLOR(r,g,b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1]
#define kLightGrayColor BIT_RGBCOLOR(235, 235, 235)
#define kDarkGrayColor BIT_RGBCOLOR(186, 186, 186)
#define kWhiteBackgroundColor BIT_RGBCOLOR(245, 245, 245)
#define kImageHeight 72
#define kImageBorderRadius 12
#define kImageLeftMargin 14
#define kImageTopMargin 12
#define kTextRow kImageTopMargin*2 + kImageHeight
@implementation BITAppStoreHeader
#pragma mark - NSObject
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
self.backgroundColor = kWhiteBackgroundColor;
}
return self;
}
- (void)dealloc {
[_headerLabel release], _headerLabel = nil;
[_middleHeaderLabel release], _middleHeaderLabel = nil;
[_subHeaderLabel release], _subHeaderLabel = nil;
[_iconImage release], _iconImage = nil;;
[super dealloc];
}
#pragma mark - UIView
- (void)drawRect:(CGRect)rect {
CGRect bounds = self.bounds;
CGFloat globalWidth = self.frame.size.width;
CGContextRef context = UIGraphicsGetCurrentContext();
// draw the gradient
NSArray *colors = [NSArray arrayWithObjects:(id)kDarkGrayColor.CGColor, (id)kLightGrayColor.CGColor, nil];
CGGradientRef gradient = CGGradientCreateWithColors(CGColorGetColorSpace((CGColorRef)[colors objectAtIndex:0]), (CFArrayRef)colors, (CGFloat[2]){0, 1});
CGPoint top = CGPointMake(CGRectGetMidX(bounds), bounds.size.height - 3);
CGPoint bottom = CGPointMake(CGRectGetMidX(bounds), CGRectGetMaxY(bounds));
CGContextDrawLinearGradient(context, gradient, top, bottom, 0);
CGGradientRelease(gradient);
// draw header name
UIColor *mainTextColor = BIT_RGBCOLOR(61, 61, 61);
UIColor *secondaryTextColor = BIT_RGBCOLOR(100, 100, 100);
UIFont *mainFont = [UIFont boldSystemFontOfSize:15];
UIFont *secondaryFont = [UIFont systemFontOfSize:10];
// float myColorValues[] = {255, 255, 255, .6};
// CGColorSpaceRef myColorSpace = CGColorSpaceCreateDeviceRGB();
// CGColorRef myColor = CGColorCreate(myColorSpace, myColorValues);
// icon
[_iconImage drawAtPoint:CGPointMake(kImageLeftMargin, kImageTopMargin)];
// shadows are a beast
// NSInteger shadowOffset = 2;
// if([[UIScreen mainScreen] scale] == 2) shadowOffset = 1;
// BITHOCKEY_IF_IOS5_OR_GREATER(shadowOffset = 1;) // iOS5 changes this - again!
//
// CGContextSetShadowWithColor(context, CGSizeMake(shadowOffset, shadowOffset), 0, myColor);
[mainTextColor set];
[_headerLabel drawInRect:CGRectMake(kTextRow, kImageTopMargin, globalWidth-kTextRow, 20) withFont:mainFont lineBreakMode:UILineBreakModeTailTruncation];
// middle
[secondaryTextColor set];
[_middleHeaderLabel drawInRect:CGRectMake(kTextRow, kImageTopMargin + 17, globalWidth-kTextRow, 20) withFont:secondaryFont lineBreakMode:UILineBreakModeTailTruncation];
// CGContextSetShadowWithColor(context, CGSizeZero, 0, nil);
// sub
[secondaryTextColor set];
[_subHeaderLabel drawAtPoint:CGPointMake(kTextRow, kImageTopMargin + 29) forWidth:globalWidth-kTextRow withFont:secondaryFont lineBreakMode:UILineBreakModeTailTruncation];
// CGColorRelease(myColor);
// CGColorSpaceRelease(myColorSpace);
}
#pragma mark - Properties
- (void)setHeaderLabel:(NSString *)anHeaderLabel {
if (_headerLabel != anHeaderLabel) {
[_headerLabel release];
_headerLabel = [anHeaderLabel copy];
[self setNeedsDisplay];
}
}
- (void)setMiddleHeaderLabel:(NSString *)aMiddleHeaderLabel {
if (_middleHeaderLabel != aMiddleHeaderLabel) {
[_middleHeaderLabel release];
_middleHeaderLabel = [aMiddleHeaderLabel copy];
[self setNeedsDisplay];
}
}
- (void)setSubHeaderLabel:(NSString *)aSubHeaderLabel {
if (_subHeaderLabel != aSubHeaderLabel) {
[_subHeaderLabel release];
_subHeaderLabel = [aSubHeaderLabel copy];
[self setNeedsDisplay];
}
}
- (void)setIconImage:(UIImage *)anIconImage {
if (_iconImage != anIconImage) {
[_iconImage release];
// scale, make borders and reflection
_iconImage = bit_imageToFitSize(anIconImage, CGSizeMake(kImageHeight, kImageHeight), YES);
_iconImage = [bit_roundedCornerImage(_iconImage, kImageBorderRadius, 0.0) retain];
[self setNeedsDisplay];
}
}
@end

81
Classes/BITStoreButton.h Normal file
View File

@ -0,0 +1,81 @@
/*
* Author: Andreas Linde <mail@andreaslinde.de>
* Peter Steinberger
*
* Copyright (c) 2012 HockeyApp, Bit Stadium GmbH.
* Copyright (c) 2011-2012 Peter Steinberger.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>
// defines a button action set (data container)
@interface BITStoreButtonData : NSObject {
CGPoint _customPadding;
}
+ (id)dataWithLabel:(NSString*)aLabel colors:(NSArray*)aColors enabled:(BOOL)flag;
@property (nonatomic, copy) NSString *label;
@property (nonatomic, retain) NSArray *colors;
@property (nonatomic, assign, getter=isEnabled) BOOL enabled;
@end
@class BITStoreButton;
@protocol BITStoreButtonDelegate
- (void)storeButtonFired:(BITStoreButton *)button;
@end
// Simulate the Paymeny-Button from the AppStore
// The interface is flexible, so there is now fixed order
@interface BITStoreButton : UIButton {
CAGradientLayer *_gradient;
CGPoint _customPadding;
}
- (id)initWithFrame:(CGRect)frame;
- (id)initWithPadding:(CGPoint)padding;
// action delegate
@property (nonatomic, assign) id<BITStoreButtonDelegate> buttonDelegate;
// change the button layer
@property (nonatomic, retain) BITStoreButtonData *buttonData;
- (void)setButtonData:(BITStoreButtonData *)aButtonData animated:(BOOL)animated;
// align helper
@property (nonatomic, assign) CGPoint customPadding;
- (void)alignToSuperview;
// helpers to mimic an AppStore button
+ (NSArray *)appStoreGreenColor;
+ (NSArray *)appStoreBlueColor;
+ (NSArray *)appStoreGrayColor;
@end

View File

@ -1,28 +1,35 @@
// /*
// Created by Peter Steinberger on 09.01.11. * Author: Andreas Linde <mail@andreaslinde.de>
// Copyright 2011-2012 Peter Steinberger. All rights reserved. * Peter Steinberger
// *
// This code was inspired by https://github.com/dhmspector/ZIStoreButton * Copyright (c) 2012 HockeyApp, Bit Stadium GmbH.
// * Copyright (c) 2011-2012 Peter Steinberger.
// Permission is hereby granted, free of charge, to any person obtaining a copy * All rights reserved.
// of this software and associated documentation files (the "Software"), to deal *
// in the Software without restriction, including without limitation the rights * Permission is hereby granted, free of charge, to any person
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * obtaining a copy of this software and associated documentation
// copies of the Software, and to permit persons to whom the Software is * files (the "Software"), to deal in the Software without
// furnished to do so, subject to the following conditions: * restriction, including without limitation the rights to use,
// * copy, modify, merge, publish, distribute, sublicense, and/or sell
// The above copyright notice and this permission notice shall be included in * copies of the Software, and to permit persons to whom the
// all copies or substantial portions of the Software. * Software is furnished to do so, subject to the following
// * conditions:
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * The above copyright notice and this permission notice shall be
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * included in all copies or substantial portions of the Software.
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// THE SOFTWARE. * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#import "PSStoreButton.h"
#import "BITStoreButton.h"
#define PS_RGBCOLOR(r,g,b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1] #define PS_RGBCOLOR(r,g,b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1]
#define PS_MIN_HEIGHT 25.0f #define PS_MIN_HEIGHT 25.0f
@ -30,12 +37,8 @@
#define PS_PADDING 12.0f #define PS_PADDING 12.0f
#define kDefaultButtonAnimationTime 0.25f #define kDefaultButtonAnimationTime 0.25f
@implementation PSStoreButtonData
@synthesize label = label_;
@synthesize colors = colors_;
@synthesize enabled = enabled_;
@implementation BITStoreButtonData
#pragma mark - NSObject #pragma mark - NSObject
@ -53,31 +56,26 @@
} }
- (void)dealloc { - (void)dealloc {
[label_ release]; [_label release], _label = nil;
[colors_ release]; [_colors release];
[super dealloc]; [super dealloc];
} }
@end @end
@interface PSStoreButton () @interface BITStoreButton ()
// call when buttonData was updated // call when buttonData was updated
- (void)updateButtonAnimated:(BOOL)animated; - (void)updateButtonAnimated:(BOOL)animated;
@end @end
@implementation PSStoreButton @implementation BITStoreButton
@synthesize buttonData = buttonData_;
@synthesize buttonDelegate = buttonDelegate_;
@synthesize customPadding = customPadding_;
#pragma mark - private #pragma mark - private
- (void)buttonPressed:(id)sender { - (void)buttonPressed:(id)sender {
[buttonDelegate_ storeButtonFired:self]; [_buttonDelegate storeButtonFired:self];
} }
- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context { - (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
@ -101,7 +99,7 @@
} }
self.enabled = self.buttonData.isEnabled; self.enabled = self.buttonData.isEnabled;
gradient_.colors = self.buttonData.colors; _gradient.colors = self.buttonData.colors;
// show white or gray text, depending on the state // show white or gray text, depending on the state
if (self.buttonData.isEnabled) { if (self.buttonData.isEnabled) {
@ -148,8 +146,8 @@
[self sizeToFit]; [self sizeToFit];
if (self.superview) { if (self.superview) {
CGRect cr = self.frame; CGRect cr = self.frame;
cr.origin.y = customPadding_.y; cr.origin.y = _customPadding.y;
cr.origin.x = self.superview.frame.size.width - cr.size.width - customPadding_.x * 2; cr.origin.x = self.superview.frame.size.width - cr.size.width - _customPadding.x * 2;
self.frame = cr; self.frame = cr;
} }
} }
@ -183,12 +181,12 @@
[self.layer addSublayer:topBorderLayer]; [self.layer addSublayer:topBorderLayer];
// main gradient layer // main gradient layer
gradient_ = [[CAGradientLayer layer] retain]; _gradient = [[CAGradientLayer layer] retain];
gradient_.locations = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0], [NSNumber numberWithFloat:1.0], nil];//[NSNumber numberWithFloat:0.500], [NSNumber numberWithFloat:0.5001], _gradient.locations = [NSArray arrayWithObjects:[NSNumber numberWithFloat:0.0], [NSNumber numberWithFloat:1.0], nil];//[NSNumber numberWithFloat:0.500], [NSNumber numberWithFloat:0.5001],
gradient_.frame = CGRectMake(0.75, 0.75, CGRectGetWidth(frame) - 1.5, CGRectGetHeight(frame) - 1.5); _gradient.frame = CGRectMake(0.75, 0.75, CGRectGetWidth(frame) - 1.5, CGRectGetHeight(frame) - 1.5);
gradient_.cornerRadius = 2.5; _gradient.cornerRadius = 2.5;
gradient_.needsDisplayOnBoundsChange = YES; _gradient.needsDisplayOnBoundsChange = YES;
[self.layer addSublayer:gradient_]; [self.layer addSublayer:_gradient];
[self bringSubviewToFront:self.titleLabel]; [self bringSubviewToFront:self.titleLabel];
} }
return self; return self;
@ -196,14 +194,14 @@
- (id)initWithPadding:(CGPoint)padding { - (id)initWithPadding:(CGPoint)padding {
if ((self = [self initWithFrame:CGRectMake(0, 0, 40, PS_MIN_HEIGHT)])) { if ((self = [self initWithFrame:CGRectMake(0, 0, 40, PS_MIN_HEIGHT)])) {
customPadding_ = padding; _customPadding = padding;
} }
return self; return self;
} }
- (void)dealloc { - (void)dealloc {
[buttonData_ release]; [_buttonData release];
[gradient_ release]; [_gradient release];
[super dealloc]; [super dealloc];
} }
@ -237,14 +235,14 @@
#pragma mark - Properties #pragma mark - Properties
- (void)setButtonData:(PSStoreButtonData *)aButtonData { - (void)setButtonData:(BITStoreButtonData *)aButtonData {
[self setButtonData:aButtonData animated:NO]; [self setButtonData:aButtonData animated:NO];
} }
- (void)setButtonData:(PSStoreButtonData *)aButtonData animated:(BOOL)animated { - (void)setButtonData:(BITStoreButtonData *)aButtonData animated:(BOOL)animated {
if (buttonData_ != aButtonData) { if (_buttonData != aButtonData) {
[buttonData_ release]; [_buttonData release];
buttonData_ = [aButtonData retain]; _buttonData = [aButtonData retain];
} }
[self updateButtonAnimated:animated]; [self updateButtonAnimated:animated];

View File

@ -33,9 +33,5 @@
#import "BITHockeyBaseViewController.h" #import "BITHockeyBaseViewController.h"
@class PSStoreButton;
@class PSAppStoreHeader;
@interface BITUpdateViewController : BITHockeyBaseViewController @interface BITUpdateViewController : BITHockeyBaseViewController
@end @end

View File

@ -31,9 +31,9 @@
#import <QuartzCore/QuartzCore.h> #import <QuartzCore/QuartzCore.h>
#import "BITHockeyHelper.h" #import "BITHockeyHelper.h"
#import "BITAppVersionMetaInfo.h" #import "BITAppVersionMetaInfo.h"
#import "PSAppStoreHeader.h" #import "BITAppStoreHeader.h"
#import "PSWebTableViewCell.h" #import "BITWebTableViewCell.h"
#import "PSStoreButton.h" #import "BITStoreButton.h"
#import "HockeySDK.h" #import "HockeySDK.h"
#import "HockeySDKPrivate.h" #import "HockeySDKPrivate.h"
@ -43,15 +43,15 @@
#define kWebCellIdentifier @"PSWebTableViewCell" #define kWebCellIdentifier @"PSWebTableViewCell"
#define kAppStoreViewHeight 90 #define kAppStoreViewHeight 99
@implementation BITUpdateViewController { @implementation BITUpdateViewController {
BOOL _kvoRegistered; BOOL _kvoRegistered;
BOOL _showAllVersions; BOOL _showAllVersions;
UIStatusBarStyle _statusBarStyle; UIStatusBarStyle _statusBarStyle;
PSAppStoreHeader *_appStoreHeader; BITAppStoreHeader *_appStoreHeader;
PSStoreButton *_appStoreButton; BITStoreButton *_appStoreButton;
id _popOverController; id _popOverController;
@ -138,11 +138,11 @@
} }
- (void)changePreviousVersionButtonBackground:(id)sender { - (void)changePreviousVersionButtonBackground:(id)sender {
[(UIButton *)sender setBackgroundColor:BIT_RGBCOLOR(183,183,183)]; [(UIButton *)sender setBackgroundColor:BIT_RGBCOLOR(245, 245, 245)];
} }
- (void)changePreviousVersionButtonBackgroundHighlighted:(id)sender { - (void)changePreviousVersionButtonBackgroundHighlighted:(id)sender {
[(UIButton *)sender setBackgroundColor:BIT_RGBCOLOR(183,183,183)]; [(UIButton *)sender setBackgroundColor:BIT_RGBCOLOR(245, 245, 245)];
} }
- (void)showHidePreviousVersionsButton { - (void)showHidePreviousVersionsButton {
@ -152,35 +152,47 @@
// align at the bottom if tableview is small // align at the bottom if tableview is small
UIView *footerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, kMinPreviousVersionButtonHeight)]; UIView *footerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, kMinPreviousVersionButtonHeight)];
footerView.autoresizingMask = UIViewAutoresizingFlexibleWidth; footerView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
footerView.backgroundColor = BIT_RGBCOLOR(200, 202, 204); footerView.backgroundColor = BIT_RGBCOLOR(245, 245, 245);
UIView *lineView1 = [[[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 1)] autorelease];
lineView1.backgroundColor = BIT_RGBCOLOR(214, 214, 214);
lineView1.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[footerView addSubview:lineView1];
UIView *lineView2 = [[[UIView alloc] initWithFrame:CGRectMake(0, 1, self.view.frame.size.width, 1)] autorelease];
lineView2.backgroundColor = BIT_RGBCOLOR(221, 221, 221);
lineView2.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[footerView addSubview:lineView2];
UIView *lineView3 = [[[UIView alloc] initWithFrame:CGRectMake(0, 1, self.view.frame.size.width, 1)] autorelease];
lineView3.backgroundColor = BIT_RGBCOLOR(255, 255, 255);
lineView3.autoresizingMask = UIViewAutoresizingFlexibleWidth;
[footerView addSubview:lineView3];
UIButton *footerButton = [UIButton buttonWithType:UIButtonTypeCustom]; UIButton *footerButton = [UIButton buttonWithType:UIButtonTypeCustom];
//footerButton.layer.shadowOffset = CGSizeMake(-2, 2); //footerButton.layer.shadowOffset = CGSizeMake(-2, 2);
footerButton.layer.shadowColor = [[UIColor blackColor] CGColor]; footerButton.layer.shadowColor = [[UIColor blackColor] CGColor];
footerButton.layer.shadowRadius = 2.0f; footerButton.layer.shadowRadius = 2.0f;
footerButton.titleLabel.font = [UIFont boldSystemFontOfSize:14]; footerButton.titleLabel.font = [UIFont boldSystemFontOfSize:14];
[footerButton setTitle:BITHockeyLocalizedString(@"UpdateShowPreviousVersions") forState:UIControlStateNormal]; [footerButton setTitle:BITHockeyLocalizedString(@"UpdateShowPreviousVersions") forState:UIControlStateNormal];
[footerButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; [footerButton setTitleColor:BIT_RGBCOLOR(61, 61, 61) forState:UIControlStateNormal];
[footerButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted]; [footerButton setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
[footerButton setBackgroundImage:bit_imageNamed(@"buttonHighlight.png", BITHOCKEYSDK_BUNDLE) forState:UIControlStateHighlighted]; [footerButton setBackgroundImage:bit_imageNamed(@"buttonHighlight.png", BITHOCKEYSDK_BUNDLE) forState:UIControlStateHighlighted];
footerButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin; footerButton.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleTopMargin;
[footerButton addTarget:self action:@selector(showPreviousVersionAction) forControlEvents:UIControlEventTouchUpInside]; [footerButton addTarget:self action:@selector(showPreviousVersionAction) forControlEvents:UIControlEventTouchUpInside];
footerButton.frame = CGRectMake(0, kMinPreviousVersionButtonHeight-44, self.view.frame.size.width, 44); footerButton.frame = CGRectMake(0, kMinPreviousVersionButtonHeight-44, self.view.frame.size.width, 44);
footerButton.backgroundColor = BIT_RGBCOLOR(183,183,183); footerButton.backgroundColor = BIT_RGBCOLOR(245, 245, 245);
[footerView addSubview:footerButton]; [footerView addSubview:footerButton];
self.tableView.tableFooterView = footerView; self.tableView.tableFooterView = footerView;
[self realignPreviousVersionButton]; [self realignPreviousVersionButton];
[footerView release]; [footerView release];
} else { } else {
self.tableView.tableFooterView = nil; self.tableView.tableFooterView = nil;
self.tableView.backgroundColor = BIT_RGBCOLOR(200, 202, 204); self.tableView.backgroundColor = BIT_RGBCOLOR(235, 235, 235);
} }
} }
- (void)configureWebCell:(PSWebTableViewCell *)cell forAppVersion:(BITAppVersionMetaInfo *)appVersion { - (void)configureWebCell:(BITWebTableViewCell *)cell forAppVersion:(BITAppVersionMetaInfo *)appVersion {
// create web view for a version // create web view for a version
NSString *installed = @""; NSString *installed = @"";
if ([appVersion.version isEqualToString:[_updateManager currentAppVersion]]) { if ([appVersion.version isEqualToString:[_updateManager currentAppVersion]]) {
installed = [NSString stringWithFormat:@"<span style=\"float:%@;text-shadow:rgba(255,255,255,0.6) 1px 1px 0px;\"><b>%@</b></span>", [appVersion isEqual:_updateManager.newestAppVersion] ? @"left" : @"right", BITHockeyLocalizedString(@"UpdateInstalled")]; installed = [NSString stringWithFormat:@"<span style=\"float:%@;\"><b>%@</b></span>", [appVersion isEqual:_updateManager.newestAppVersion] ? @"left" : @"right", BITHockeyLocalizedString(@"UpdateInstalled")];
} }
if ([appVersion isEqual:_updateManager.newestAppVersion]) { if ([appVersion isEqual:_updateManager.newestAppVersion]) {
@ -188,12 +200,12 @@
installed = [NSString stringWithFormat:@"<p>&nbsp;%@</p>", installed]; installed = [NSString stringWithFormat:@"<p>&nbsp;%@</p>", installed];
cell.webViewContent = [NSString stringWithFormat:@"%@%@", installed, appVersion.notes]; cell.webViewContent = [NSString stringWithFormat:@"%@%@", installed, appVersion.notes];
} else { } else {
cell.webViewContent = [NSString stringWithFormat:@"<div style=\"min-height:200px;vertical-align:middle;text-align:center;text-shadow:rgba(255,255,255,0.6) 1px 1px 0px;\">%@</div>", BITHockeyLocalizedString(@"UpdateNoReleaseNotesAvailable")]; cell.webViewContent = [NSString stringWithFormat:@"<div style=\"min-height:200px;vertical-align:middle;text-align:center;\">%@</div>", BITHockeyLocalizedString(@"UpdateNoReleaseNotesAvailable")];
} }
} else { } else {
cell.webViewContent = [NSString stringWithFormat:@"<p><b style=\"text-shadow:rgba(255,255,255,0.6) 1px 1px 0px;\">%@</b>%@<br/><small>%@</small></p><p>%@</p>", [appVersion versionString], installed, [appVersion dateString], [appVersion notesOrEmptyString]]; cell.webViewContent = [NSString stringWithFormat:@"<p><b>%@</b>%@<br/><small>%@</small></p><p>%@</p>", [appVersion versionString], installed, [appVersion dateString], [appVersion notesOrEmptyString]];
} }
cell.cellBackgroundColor = BIT_RGBCOLOR(200, 202, 204); cell.cellBackgroundColor = BIT_RGBCOLOR(235, 235, 235);
[cell addWebView]; [cell addWebView];
// hack // hack
@ -243,28 +255,28 @@
#pragma mark - View lifecycle #pragma mark - View lifecycle
- (CAGradientLayer *)backgroundLayer { //- (CAGradientLayer *)backgroundLayer {
UIColor *colorOne = [UIColor colorWithWhite:0.9 alpha:1.0]; // UIColor *colorOne = [UIColor colorWithWhite:0.9 alpha:1.0];
UIColor *colorTwo = [UIColor colorWithHue:0.625 saturation:0.0 brightness:0.85 alpha:1.0]; // UIColor *colorTwo = [UIColor colorWithHue:0.625 saturation:0.0 brightness:0.85 alpha:1.0];
UIColor *colorThree = [UIColor colorWithHue:0.625 saturation:0.0 brightness:0.7 alpha:1.0]; // UIColor *colorThree = [UIColor colorWithHue:0.625 saturation:0.0 brightness:0.7 alpha:1.0];
UIColor *colorFour = [UIColor colorWithHue:0.625 saturation:0.0 brightness:0.4 alpha:1.0]; // UIColor *colorFour = [UIColor colorWithHue:0.625 saturation:0.0 brightness:0.4 alpha:1.0];
//
NSArray *colors = [NSArray arrayWithObjects:(id)colorOne.CGColor, colorTwo.CGColor, colorThree.CGColor, colorFour.CGColor, nil]; // NSArray *colors = [NSArray arrayWithObjects:(id)colorOne.CGColor, colorTwo.CGColor, colorThree.CGColor, colorFour.CGColor, nil];
//
NSNumber *stopOne = [NSNumber numberWithFloat:0.0]; // NSNumber *stopOne = [NSNumber numberWithFloat:0.0];
NSNumber *stopTwo = [NSNumber numberWithFloat:0.02]; // NSNumber *stopTwo = [NSNumber numberWithFloat:0.02];
NSNumber *stopThree = [NSNumber numberWithFloat:0.99]; // NSNumber *stopThree = [NSNumber numberWithFloat:0.99];
NSNumber *stopFour = [NSNumber numberWithFloat:1.0]; // NSNumber *stopFour = [NSNumber numberWithFloat:1.0];
//
NSArray *locations = [NSArray arrayWithObjects:stopOne, stopTwo, stopThree, stopFour, nil]; // NSArray *locations = [NSArray arrayWithObjects:stopOne, stopTwo, stopThree, stopFour, nil];
//
CAGradientLayer *headerLayer = [CAGradientLayer layer]; // CAGradientLayer *headerLayer = [CAGradientLayer layer];
//headerLayer.frame = CGRectMake(0.0, 0.0, 320.0, 77.0); // //headerLayer.frame = CGRectMake(0.0, 0.0, 320.0, 77.0);
headerLayer.colors = colors; // headerLayer.colors = colors;
headerLayer.locations = locations; // headerLayer.locations = locations;
//
return headerLayer; // return headerLayer;
} //}
- (void)viewDidLoad { - (void)viewDidLoad {
[super viewDidLoad]; [super viewDidLoad];
@ -280,7 +292,7 @@
[_updateManager addObserver:self forKeyPath:@"apps" options:0 context:nil]; [_updateManager addObserver:self forKeyPath:@"apps" options:0 context:nil];
_kvoRegistered = YES; _kvoRegistered = YES;
self.tableView.backgroundColor = BIT_RGBCOLOR(200, 202, 204); self.tableView.backgroundColor = BIT_RGBCOLOR(235, 235, 235);
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
UIView *topView = [[[UIView alloc] initWithFrame:CGRectMake(0, -(600-kAppStoreViewHeight), self.view.frame.size.width, 600)] autorelease]; UIView *topView = [[[UIView alloc] initWithFrame:CGRectMake(0, -(600-kAppStoreViewHeight), self.view.frame.size.width, 600)] autorelease];
@ -288,7 +300,7 @@
topView.backgroundColor = BIT_RGBCOLOR(140, 141, 142); topView.backgroundColor = BIT_RGBCOLOR(140, 141, 142);
[self.tableView addSubview:topView]; [self.tableView addSubview:topView];
_appStoreHeader = [[PSAppStoreHeader alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, kAppStoreViewHeight)]; _appStoreHeader = [[BITAppStoreHeader alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, kAppStoreViewHeight)];
[self updateAppStoreHeader]; [self updateAppStoreHeader];
NSString *iconString = nil; NSString *iconString = nil;
@ -309,17 +321,20 @@
if (icons) { if (icons) {
BOOL useHighResIcon = NO; BOOL useHighResIcon = NO;
BOOL useiPadIcon = NO;
if ([UIScreen mainScreen].scale == 2.0f) useHighResIcon = YES; if ([UIScreen mainScreen].scale == 2.0f) useHighResIcon = YES;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) useiPadIcon = YES;
for(NSString *icon in icons) { for(NSString *icon in icons) {
iconString = icon; iconString = icon;
UIImage *iconImage = [UIImage imageNamed:icon]; UIImage *iconImage = [UIImage imageNamed:icon];
if (iconImage.size.height == 57 && !useHighResIcon) { if (
// found! (iconImage.size.height == 57 && !useHighResIcon && !useiPadIcon) ||
break; (iconImage.size.height == 114 && useHighResIcon && !useiPadIcon) ||
} (iconImage.size.height == 72 && !useHighResIcon && useiPadIcon) ||
if (iconImage.size.height == 114 && useHighResIcon) { (iconImage.size.height == 144 && useHighResIcon && useiPadIcon)
) {
// found! // found!
break; break;
} }
@ -340,11 +355,11 @@
self.tableView.tableHeaderView = _appStoreHeader; self.tableView.tableHeaderView = _appStoreHeader;
PSStoreButton *storeButton = [[[PSStoreButton alloc] initWithPadding:CGPointMake(5, 40)] autorelease]; BITStoreButton *storeButton = [[[BITStoreButton alloc] initWithPadding:CGPointMake(5, 58)] autorelease];
storeButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin; storeButton.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin;
storeButton.buttonDelegate = self; storeButton.buttonDelegate = self;
[self.tableView.tableHeaderView addSubview:storeButton]; [self.tableView.tableHeaderView addSubview:storeButton];
storeButton.buttonData = [PSStoreButtonData dataWithLabel:@"" colors:[PSStoreButton appStoreGrayColor] enabled:NO]; storeButton.buttonData = [BITStoreButtonData dataWithLabel:@"" colors:[BITStoreButton appStoreGrayColor] enabled:NO];
[storeButton alignToSuperview]; [storeButton alignToSuperview];
_appStoreButton = [storeButton retain]; _appStoreButton = [storeButton retain];
self.appStoreButtonState = AppStoreButtonStateCheck; self.appStoreButtonState = AppStoreButtonStateCheck;
@ -394,7 +409,7 @@
} }
} }
PSWebTableViewCell *cell = [[[PSWebTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kWebCellIdentifier] autorelease]; BITWebTableViewCell *cell = [[[BITWebTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kWebCellIdentifier] autorelease];
[self configureWebCell:cell forAppVersion:appVersion]; [self configureWebCell:cell forAppVersion:appVersion];
[_cells addObject:cell]; [_cells addObject:cell];
@ -421,7 +436,7 @@
} }
} }
PSWebTableViewCell *cell = [[[PSWebTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kWebCellIdentifier] autorelease]; BITWebTableViewCell *cell = [[[BITWebTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kWebCellIdentifier] autorelease];
[self configureWebCell:cell forAppVersion:appVersion]; [self configureWebCell:cell forAppVersion:appVersion];
[_cells addObject:cell]; [_cells addObject:cell];
} }
@ -440,17 +455,17 @@
CGFloat rowHeight = 0; CGFloat rowHeight = 0;
if ([_cells count] > (NSUInteger)indexPath.row) { if ([_cells count] > (NSUInteger)indexPath.row) {
PSWebTableViewCell *cell = [_cells objectAtIndex:indexPath.row]; BITWebTableViewCell *cell = [_cells objectAtIndex:indexPath.row];
rowHeight = cell.webViewSize.height; rowHeight = cell.webViewSize.height;
} }
if ([_updateManager.appVersions count] > 1 && !_showAllVersions) { if ([_updateManager.appVersions count] > 1 && !_showAllVersions) {
self.tableView.backgroundColor = BIT_RGBCOLOR(183, 183, 183); self.tableView.backgroundColor = BIT_RGBCOLOR(245, 245, 245);
} }
if (rowHeight == 0) { if (rowHeight == 0) {
rowHeight = indexPath.row == 0 ? 250 : 44; // fill screen on startup rowHeight = indexPath.row == 0 ? 250 : 44; // fill screen on startup
self.tableView.backgroundColor = BIT_RGBCOLOR(200, 202, 204); self.tableView.backgroundColor = BIT_RGBCOLOR(235, 235, 235);
} }
return rowHeight; return rowHeight;
@ -516,26 +531,26 @@
switch (anAppStoreButtonState) { switch (anAppStoreButtonState) {
case AppStoreButtonStateOffline: case AppStoreButtonStateOffline:
[_appStoreButton setButtonData:[PSStoreButtonData dataWithLabel:BITHockeyLocalizedString(@"UpdateButtonOffline") colors:[PSStoreButton appStoreGrayColor] enabled:NO] animated:animated]; [_appStoreButton setButtonData:[BITStoreButtonData dataWithLabel:BITHockeyLocalizedString(@"UpdateButtonOffline") colors:[BITStoreButton appStoreGrayColor] enabled:NO] animated:animated];
break; break;
case AppStoreButtonStateCheck: case AppStoreButtonStateCheck:
[_appStoreButton setButtonData:[PSStoreButtonData dataWithLabel:BITHockeyLocalizedString(@"UpdateButtonCheck") colors:[PSStoreButton appStoreGreenColor] enabled:YES] animated:animated]; [_appStoreButton setButtonData:[BITStoreButtonData dataWithLabel:BITHockeyLocalizedString(@"UpdateButtonCheck") colors:[BITStoreButton appStoreGreenColor] enabled:YES] animated:animated];
break; break;
case AppStoreButtonStateSearching: case AppStoreButtonStateSearching:
[_appStoreButton setButtonData:[PSStoreButtonData dataWithLabel:BITHockeyLocalizedString(@"UpdateButtonSearching") colors:[PSStoreButton appStoreGrayColor] enabled:NO] animated:animated]; [_appStoreButton setButtonData:[BITStoreButtonData dataWithLabel:BITHockeyLocalizedString(@"UpdateButtonSearching") colors:[BITStoreButton appStoreGrayColor] enabled:NO] animated:animated];
break; break;
case AppStoreButtonStateUpdate: case AppStoreButtonStateUpdate:
[_appStoreButton setButtonData:[PSStoreButtonData dataWithLabel:BITHockeyLocalizedString(@"UpdateButtonUpdate") colors:[PSStoreButton appStoreBlueColor] enabled:YES] animated:animated]; [_appStoreButton setButtonData:[BITStoreButtonData dataWithLabel:BITHockeyLocalizedString(@"UpdateButtonUpdate") colors:[BITStoreButton appStoreBlueColor] enabled:YES] animated:animated];
break; break;
case AppStoreButtonStateInstalling: case AppStoreButtonStateInstalling:
[_appStoreButton setButtonData:[PSStoreButtonData dataWithLabel:BITHockeyLocalizedString(@"UpdateButtonInstalling") colors:[PSStoreButton appStoreGrayColor] enabled:NO] animated:animated]; [_appStoreButton setButtonData:[BITStoreButtonData dataWithLabel:BITHockeyLocalizedString(@"UpdateButtonInstalling") colors:[BITStoreButton appStoreGrayColor] enabled:NO] animated:animated];
break; break;
default: default:
break; break;
} }
} }
- (void)storeButtonFired:(PSStoreButton *)button { - (void)storeButtonFired:(BITStoreButton *)button {
switch (_appStoreButtonState) { switch (_appStoreButtonState) {
case AppStoreButtonStateCheck: case AppStoreButtonStateCheck:
[_updateManager checkForUpdateShowFeedback:YES]; [_updateManager checkForUpdateShowFeedback:YES];

View File

@ -29,7 +29,7 @@
*/ */
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
#import "PSStoreButton.h" #import "BITStoreButton.h"
typedef enum { typedef enum {
AppStoreButtonStateOffline, AppStoreButtonStateOffline,
@ -44,7 +44,7 @@ typedef enum {
@protocol PSStoreButtonDelegate; @protocol PSStoreButtonDelegate;
@interface BITUpdateViewController() <PSStoreButtonDelegate> { @interface BITUpdateViewController() <BITStoreButtonDelegate> {
} }
@property (nonatomic, assign) BITUpdateManager *updateManager; @property (nonatomic, assign) BITUpdateManager *updateManager;

View File

@ -0,0 +1,44 @@
/*
* Author: Andreas Linde <mail@andreaslinde.de>
* Peter Steinberger
*
* Copyright (c) 2012 HockeyApp, Bit Stadium GmbH.
* Copyright (c) 2011-2012 Peter Steinberger.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface BITWebTableViewCell : UITableViewCell <UIWebViewDelegate>
@property (nonatomic, retain) UIWebView *webView;
@property (nonatomic, copy) NSString *webViewContent;
@property (nonatomic, assign) CGSize webViewSize;
@property (nonatomic, retain) UIColor *cellBackgroundColor;
- (void)addWebView;
@end

View File

@ -1,36 +1,44 @@
// /*
// Created by Peter Steinberger on 04.02.11. * Author: Andreas Linde <mail@andreaslinde.de>
// Copyright 2011-2012 Peter Steinberger. All rights reserved. * Peter Steinberger
// *
// Permission is hereby granted, free of charge, to any person obtaining a copy * Copyright (c) 2012 HockeyApp, Bit Stadium GmbH.
// of this software and associated documentation files (the "Software"), to deal * Copyright (c) 2011-2012 Peter Steinberger.
// in the Software without restriction, including without limitation the rights * All rights reserved.
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell *
// copies of the Software, and to permit persons to whom the Software is * Permission is hereby granted, free of charge, to any person
// furnished to do so, subject to the following conditions: * obtaining a copy of this software and associated documentation
// * files (the "Software"), to deal in the Software without
// The above copyright notice and this permission notice shall be included in * restriction, including without limitation the rights to use,
// all copies or substantial portions of the Software. * copy, modify, merge, publish, distribute, sublicense, and/or sell
// * copies of the Software, and to permit persons to whom the
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * Software is furnished to do so, subject to the following
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * conditions:
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * The above copyright notice and this permission notice shall be
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * included in all copies or substantial portions of the Software.
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN *
// THE SOFTWARE. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#import "PSWebTableViewCell.h" #import "BITWebTableViewCell.h"
@implementation PSWebTableViewCell @implementation BITWebTableViewCell
static NSString* PSWebTableViewCellHtmlTemplate = @"\ static NSString* BITWebTableViewCellHtmlTemplate = @"\
<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\ <!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\
<html xmlns=\"http://www.w3.org/1999/xhtml\">\ <html xmlns=\"http://www.w3.org/1999/xhtml\">\
<head>\ <head>\
<style type=\"text/css\">\ <style type=\"text/css\">\
body { font: 13px 'Helvetica Neue', Helvetica; word-wrap:break-word; padding:8px;} p {margin:0;} ul {padding-left: 18px;}\ body { font: 13px 'Helvetica Neue', Helvetica; color:#626262; word-wrap:break-word; padding:8px;} p {margin:0;} ul {padding-left: 18px;}\
</style>\ </style>\
<meta name=\"viewport\" content=\"user-scalable=no width=%@\" /></head>\ <meta name=\"viewport\" content=\"user-scalable=no width=%@\" /></head>\
<body>\ <body>\
@ -39,27 +47,22 @@ body { font: 13px 'Helvetica Neue', Helvetica; word-wrap:break-word; padding:8px
</html>\ </html>\
"; ";
@synthesize webView = webView_;
@synthesize webViewContent = webViewContent_;
@synthesize webViewSize = webViewSize_;
@synthesize cellBackgroundColor = cellBackgroundColor_;
#pragma mark - private #pragma mark - private
- (void)addWebView { - (void)addWebView {
if(webViewContent_) { if(_webViewContent) {
CGRect webViewRect = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height); CGRect webViewRect = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
if(!webView_) { if(!_webView) {
webView_ = [[[UIWebView alloc] initWithFrame:webViewRect] retain]; _webView = [[[UIWebView alloc] initWithFrame:webViewRect] retain];
[self addSubview:webView_]; [self addSubview:_webView];
webView_.hidden = YES; _webView.hidden = YES;
webView_.backgroundColor = self.cellBackgroundColor; _webView.backgroundColor = self.cellBackgroundColor;
webView_.opaque = NO; _webView.opaque = NO;
webView_.delegate = self; _webView.delegate = self;
webView_.autoresizingMask = UIViewAutoresizingFlexibleWidth; _webView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
for(UIView* subView in webView_.subviews){ for(UIView* subView in _webView.subviews){
if([subView isKindOfClass:[UIScrollView class]]){ if([subView isKindOfClass:[UIScrollView class]]){
// disable scrolling // disable scrolling
UIScrollView *sv = (UIScrollView *)subView; UIScrollView *sv = (UIScrollView *)subView;
@ -76,38 +79,38 @@ body { font: 13px 'Helvetica Neue', Helvetica; word-wrap:break-word; padding:8px
} }
} }
else else
webView_.frame = webViewRect; _webView.frame = webViewRect;
NSString *deviceWidth = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ? [NSString stringWithFormat:@"%.0f", CGRectGetWidth(self.bounds)] : @"device-width"; NSString *deviceWidth = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad ? [NSString stringWithFormat:@"%.0f", CGRectGetWidth(self.bounds)] : @"device-width";
//HockeySDKLog(@"%@\n%@\%@", PSWebTableViewCellHtmlTemplate, deviceWidth, self.webViewContent); //HockeySDKLog(@"%@\n%@\%@", PSWebTableViewCellHtmlTemplate, deviceWidth, self.webViewContent);
NSString *contentHtml = [NSString stringWithFormat:PSWebTableViewCellHtmlTemplate, deviceWidth, self.webViewContent]; NSString *contentHtml = [NSString stringWithFormat:BITWebTableViewCellHtmlTemplate, deviceWidth, self.webViewContent];
[webView_ loadHTMLString:contentHtml baseURL:nil]; [_webView loadHTMLString:contentHtml baseURL:nil];
} }
} }
- (void)showWebView { - (void)showWebView {
webView_.hidden = NO; _webView.hidden = NO;
self.textLabel.text = @""; self.textLabel.text = @"";
[self setNeedsDisplay]; [self setNeedsDisplay];
} }
- (void)removeWebView { - (void)removeWebView {
if(webView_) { if(_webView) {
webView_.delegate = nil; _webView.delegate = nil;
[webView_ resignFirstResponder]; [_webView resignFirstResponder];
[webView_ removeFromSuperview]; [_webView removeFromSuperview];
[webView_ release]; [_webView release];
} }
webView_ = nil; _webView = nil;
[self setNeedsDisplay]; [self setNeedsDisplay];
} }
- (void)setWebViewContent:(NSString *)aWebViewContent { - (void)setWebViewContent:(NSString *)aWebViewContent {
if (webViewContent_ != aWebViewContent) { if (_webViewContent != aWebViewContent) {
[webViewContent_ release]; [_webViewContent release];
webViewContent_ = [aWebViewContent retain]; _webViewContent = [aWebViewContent retain];
// add basic accessiblity (prevents "snarfed from ivar layout") logs // add basic accessiblity (prevents "snarfed from ivar layout") logs
self.accessibilityLabel = aWebViewContent; self.accessibilityLabel = aWebViewContent;
@ -126,7 +129,7 @@ body { font: 13px 'Helvetica Neue', Helvetica; word-wrap:break-word; padding:8px
- (void)dealloc { - (void)dealloc {
[self removeWebView]; [self removeWebView];
[webViewContent_ release]; [_webViewContent release], _webViewContent = nil;;
[super dealloc]; [super dealloc];
} }
@ -163,18 +166,18 @@ body { font: 13px 'Helvetica Neue', Helvetica; word-wrap:break-word; padding:8px
- (void)webViewDidFinishLoad:(UIWebView *)webView { - (void)webViewDidFinishLoad:(UIWebView *)webView {
if(webViewContent_) if(_webViewContent)
[self showWebView]; [self showWebView];
CGRect frame = webView_.frame; CGRect frame = _webView.frame;
frame.size.height = 1; frame.size.height = 1;
webView_.frame = frame; _webView.frame = frame;
CGSize fittingSize = [webView_ sizeThatFits:CGSizeZero]; CGSize fittingSize = [_webView sizeThatFits:CGSizeZero];
frame.size = fittingSize; frame.size = fittingSize;
webView_.frame = frame; _webView.frame = frame;
// sizeThatFits is not reliable - use javascript for optimal height // sizeThatFits is not reliable - use javascript for optimal height
NSString *output = [webView_ stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight;"]; NSString *output = [_webView stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight;"];
self.webViewSize = CGSizeMake(fittingSize.width, [output integerValue]); self.webViewSize = CGSizeMake(fittingSize.width, [output integerValue]);
} }

View File

@ -1,39 +0,0 @@
//
// Created by Peter Steinberger on 09.01.11.
// Copyright (c) 2011-2012 Peter Steinberger. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <UIKit/UIKit.h>
@interface PSAppStoreHeader : UIView {
NSString *headerLabel_;
NSString *middleHeaderLabel_;
NSString *subHeaderLabel;
UIImage *iconImage_;
UIImage *reflectedImage_;
}
@property (nonatomic, copy) NSString *headerLabel;
@property (nonatomic, copy) NSString *middleHeaderLabel;
@property (nonatomic, copy) NSString *subHeaderLabel;
@property (nonatomic, retain) UIImage *iconImage;
@end

View File

@ -1,165 +0,0 @@
//
// Created by Peter Steinberger on 09.01.11.
// Copyright (c) 2011-2012 Peter Steinberger. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import "PSAppStoreHeader.h"
#import "BITHockeyHelper.h"
#import "HockeySDKPrivate.h"
#define BIT_RGBCOLOR(r,g,b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1]
#define kLightGrayColor BIT_RGBCOLOR(200, 202, 204)
#define kDarkGrayColor BIT_RGBCOLOR(140, 141, 142)
#define kImageHeight 57
#define kReflectionHeight 20
#define kImageBorderRadius 10
#define kImageMargin 8
#define kTextRow kImageMargin*2 + kImageHeight
@implementation PSAppStoreHeader
@synthesize headerLabel = headerLabel_;
@synthesize middleHeaderLabel = middleHeaderLabel_;
@synthesize subHeaderLabel;
@synthesize iconImage = iconImage_;
#pragma mark - NSObject
- (id)initWithFrame:(CGRect)frame {
if ((self = [super initWithFrame:frame])) {
self.autoresizingMask = UIViewAutoresizingFlexibleWidth;
self.backgroundColor = kLightGrayColor;
}
return self;
}
- (void)dealloc {
[headerLabel_ release];
[middleHeaderLabel_ release];
[subHeaderLabel release];
[iconImage_ release];
[super dealloc];
}
#pragma mark - UIView
- (void)drawRect:(CGRect)rect {
CGRect bounds = self.bounds;
CGFloat globalWidth = self.frame.size.width;
CGContextRef context = UIGraphicsGetCurrentContext();
// draw the gradient
NSArray *colors = [NSArray arrayWithObjects:(id)kDarkGrayColor.CGColor, (id)kLightGrayColor.CGColor, nil];
CGGradientRef gradient = CGGradientCreateWithColors(CGColorGetColorSpace((CGColorRef)[colors objectAtIndex:0]), (CFArrayRef)colors, (CGFloat[2]){0, 1});
CGPoint top = CGPointMake(CGRectGetMidX(bounds), bounds.origin.y);
CGPoint bottom = CGPointMake(CGRectGetMidX(bounds), CGRectGetMaxY(bounds)-kReflectionHeight);
CGContextDrawLinearGradient(context, gradient, top, bottom, 0);
CGGradientRelease(gradient);
// draw header name
UIColor *mainTextColor = BIT_RGBCOLOR(0,0,0);
UIColor *secondaryTextColor = BIT_RGBCOLOR(48,48,48);
UIFont *mainFont = [UIFont boldSystemFontOfSize:20];
UIFont *secondaryFont = [UIFont boldSystemFontOfSize:12];
UIFont *smallFont = [UIFont systemFontOfSize:12];
float myColorValues[] = {255, 255, 255, .6};
CGColorSpaceRef myColorSpace = CGColorSpaceCreateDeviceRGB();
CGColorRef myColor = CGColorCreate(myColorSpace, myColorValues);
// icon
[iconImage_ drawAtPoint:CGPointMake(kImageMargin, kImageMargin)];
[reflectedImage_ drawAtPoint:CGPointMake(kImageMargin, kImageMargin+kImageHeight)];
// shadows are a beast
NSInteger shadowOffset = 2;
if([[UIScreen mainScreen] scale] == 2) shadowOffset = 1;
BITHOCKEY_IF_IOS5_OR_GREATER(shadowOffset = 1;) // iOS5 changes this - again!
CGContextSetShadowWithColor(context, CGSizeMake(shadowOffset, shadowOffset), 0, myColor);
[mainTextColor set];
[headerLabel_ drawInRect:CGRectMake(kTextRow, kImageMargin, globalWidth-kTextRow, 20) withFont:mainFont lineBreakMode:UILineBreakModeTailTruncation];
// middle
[secondaryTextColor set];
[middleHeaderLabel_ drawInRect:CGRectMake(kTextRow, kImageMargin + 25, globalWidth-kTextRow, 20) withFont:secondaryFont lineBreakMode:UILineBreakModeTailTruncation];
CGContextSetShadowWithColor(context, CGSizeZero, 0, nil);
// sub
[secondaryTextColor set];
[subHeaderLabel drawAtPoint:CGPointMake(kTextRow, kImageMargin+kImageHeight-12) forWidth:globalWidth-kTextRow withFont:smallFont lineBreakMode:UILineBreakModeTailTruncation];
CGColorRelease(myColor);
CGColorSpaceRelease(myColorSpace);
}
#pragma mark - Properties
- (void)setHeaderLabel:(NSString *)anHeaderLabel {
if (headerLabel_ != anHeaderLabel) {
[headerLabel_ release];
headerLabel_ = [anHeaderLabel copy];
[self setNeedsDisplay];
}
}
- (void)setMiddleHeaderLabel:(NSString *)aMiddleHeaderLabel {
if (middleHeaderLabel_ != aMiddleHeaderLabel) {
[middleHeaderLabel_ release];
middleHeaderLabel_ = [aMiddleHeaderLabel copy];
[self setNeedsDisplay];
}
}
- (void)setSubHeaderLabel:(NSString *)aSubHeaderLabel {
if (subHeaderLabel != aSubHeaderLabel) {
[subHeaderLabel release];
subHeaderLabel = [aSubHeaderLabel copy];
[self setNeedsDisplay];
}
}
- (void)setIconImage:(UIImage *)anIconImage {
if (iconImage_ != anIconImage) {
[iconImage_ release];
// scale, make borders and reflection
iconImage_ = bit_imageToFitSize(anIconImage, CGSizeMake(kImageHeight, kImageHeight), YES);
iconImage_ = [bit_roundedCornerImage(iconImage_, kImageBorderRadius, 0.0) retain];
// create reflected image
[reflectedImage_ release];
reflectedImage_ = nil;
if (anIconImage) {
reflectedImage_ = [bit_reflectedImageWithHeight(iconImage_, kReflectionHeight, 0.5, 0.0) retain];
}
[self setNeedsDisplay];
}
}
@end

View File

@ -1,78 +0,0 @@
//
// Created by Peter Steinberger on 09.01.11.
// Copyright 2011-2012 Peter Steinberger. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <QuartzCore/QuartzCore.h>
#import <UIKit/UIKit.h>
// defines a button action set (data container)
@interface PSStoreButtonData : NSObject {
CGPoint customPadding_;
NSString *label_;
NSArray *colors_;
BOOL enabled_;
}
+ (id)dataWithLabel:(NSString*)aLabel colors:(NSArray*)aColors enabled:(BOOL)flag;
@property (nonatomic, copy) NSString *label;
@property (nonatomic, retain) NSArray *colors;
@property (nonatomic, assign, getter=isEnabled) BOOL enabled;
@end
@class PSStoreButton;
@protocol PSStoreButtonDelegate
- (void)storeButtonFired:(PSStoreButton *)button;
@end
// Simulate the Paymeny-Button from the AppStore
// The interface is flexible, so there is now fixed order
@interface PSStoreButton : UIButton {
PSStoreButtonData *buttonData_;
id<PSStoreButtonDelegate> buttonDelegate_;
CAGradientLayer *gradient_;
CGPoint customPadding_;
}
- (id)initWithFrame:(CGRect)frame;
- (id)initWithPadding:(CGPoint)padding;
// action delegate
@property (nonatomic, assign) id<PSStoreButtonDelegate> buttonDelegate;
// change the button layer
@property (nonatomic, retain) PSStoreButtonData *buttonData;
- (void)setButtonData:(PSStoreButtonData *)aButtonData animated:(BOOL)animated;
// align helper
@property (nonatomic, assign) CGPoint customPadding;
- (void)alignToSuperview;
// helpers to mimic an AppStore button
+ (NSArray *)appStoreGreenColor;
+ (NSArray *)appStoreBlueColor;
+ (NSArray *)appStoreGrayColor;
@end

View File

@ -1,41 +0,0 @@
//
// Created by Peter Steinberger on 04.02.11.
// Copyright 2011-2012 Peter Steinberger. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@interface PSWebTableViewCell : UITableViewCell <UIWebViewDelegate> {
UIWebView *webView_;
NSString *webViewContent_;
CGSize webViewSize_;
UIColor *cellBackgroundColor_;
}
@property (nonatomic, retain) UIWebView *webView;
@property (nonatomic, copy) NSString *webViewContent;
@property (nonatomic, assign) CGSize webViewSize;
@property (nonatomic, retain) UIColor *cellBackgroundColor;
- (void)addWebView;
@end

View File

@ -63,12 +63,12 @@
1E49A4BB161222B900463151 /* BITHockeyBaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E49A4A4161222B900463151 /* BITHockeyBaseViewController.m */; }; 1E49A4BB161222B900463151 /* BITHockeyBaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E49A4A4161222B900463151 /* BITHockeyBaseViewController.m */; };
1E49A4BE161222B900463151 /* BITHockeyHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E49A4A5161222B900463151 /* BITHockeyHelper.h */; }; 1E49A4BE161222B900463151 /* BITHockeyHelper.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E49A4A5161222B900463151 /* BITHockeyHelper.h */; };
1E49A4C1161222B900463151 /* BITHockeyHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E49A4A6161222B900463151 /* BITHockeyHelper.m */; }; 1E49A4C1161222B900463151 /* BITHockeyHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E49A4A6161222B900463151 /* BITHockeyHelper.m */; };
1E49A4C4161222B900463151 /* PSAppStoreHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E49A4A7161222B900463151 /* PSAppStoreHeader.h */; }; 1E49A4C4161222B900463151 /* BITAppStoreHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E49A4A7161222B900463151 /* BITAppStoreHeader.h */; };
1E49A4C7161222B900463151 /* PSAppStoreHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E49A4A8161222B900463151 /* PSAppStoreHeader.m */; }; 1E49A4C7161222B900463151 /* BITAppStoreHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E49A4A8161222B900463151 /* BITAppStoreHeader.m */; };
1E49A4CA161222B900463151 /* PSStoreButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E49A4A9161222B900463151 /* PSStoreButton.h */; }; 1E49A4CA161222B900463151 /* BITStoreButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E49A4A9161222B900463151 /* BITStoreButton.h */; };
1E49A4CD161222B900463151 /* PSStoreButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E49A4AA161222B900463151 /* PSStoreButton.m */; }; 1E49A4CD161222B900463151 /* BITStoreButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E49A4AA161222B900463151 /* BITStoreButton.m */; };
1E49A4D0161222B900463151 /* PSWebTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E49A4AB161222B900463151 /* PSWebTableViewCell.h */; }; 1E49A4D0161222B900463151 /* BITWebTableViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E49A4AB161222B900463151 /* BITWebTableViewCell.h */; };
1E49A4D3161222B900463151 /* PSWebTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E49A4AC161222B900463151 /* PSWebTableViewCell.m */; }; 1E49A4D3161222B900463151 /* BITWebTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E49A4AC161222B900463151 /* BITWebTableViewCell.m */; };
1E49A4D8161222D400463151 /* HockeySDKPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E49A4D4161222D400463151 /* HockeySDKPrivate.h */; }; 1E49A4D8161222D400463151 /* HockeySDKPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E49A4D4161222D400463151 /* HockeySDKPrivate.h */; };
1E49A4DB161222D400463151 /* HockeySDKPrivate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E49A4D5161222D400463151 /* HockeySDKPrivate.m */; }; 1E49A4DB161222D400463151 /* HockeySDKPrivate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E49A4D5161222D400463151 /* HockeySDKPrivate.m */; };
1E5954D315B6F24A00A03429 /* BITHockeyManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E41EB466148D7BF50015DEDC /* BITHockeyManager.m */; }; 1E5954D315B6F24A00A03429 /* BITHockeyManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E41EB466148D7BF50015DEDC /* BITHockeyManager.m */; };
@ -151,12 +151,12 @@
1E49A4A4161222B900463151 /* BITHockeyBaseViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BITHockeyBaseViewController.m; sourceTree = "<group>"; }; 1E49A4A4161222B900463151 /* BITHockeyBaseViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BITHockeyBaseViewController.m; sourceTree = "<group>"; };
1E49A4A5161222B900463151 /* BITHockeyHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BITHockeyHelper.h; sourceTree = "<group>"; }; 1E49A4A5161222B900463151 /* BITHockeyHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BITHockeyHelper.h; sourceTree = "<group>"; };
1E49A4A6161222B900463151 /* BITHockeyHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BITHockeyHelper.m; sourceTree = "<group>"; }; 1E49A4A6161222B900463151 /* BITHockeyHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BITHockeyHelper.m; sourceTree = "<group>"; };
1E49A4A7161222B900463151 /* PSAppStoreHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSAppStoreHeader.h; sourceTree = "<group>"; }; 1E49A4A7161222B900463151 /* BITAppStoreHeader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BITAppStoreHeader.h; sourceTree = "<group>"; };
1E49A4A8161222B900463151 /* PSAppStoreHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PSAppStoreHeader.m; sourceTree = "<group>"; }; 1E49A4A8161222B900463151 /* BITAppStoreHeader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BITAppStoreHeader.m; sourceTree = "<group>"; };
1E49A4A9161222B900463151 /* PSStoreButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSStoreButton.h; sourceTree = "<group>"; }; 1E49A4A9161222B900463151 /* BITStoreButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BITStoreButton.h; sourceTree = "<group>"; };
1E49A4AA161222B900463151 /* PSStoreButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PSStoreButton.m; sourceTree = "<group>"; }; 1E49A4AA161222B900463151 /* BITStoreButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BITStoreButton.m; sourceTree = "<group>"; };
1E49A4AB161222B900463151 /* PSWebTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PSWebTableViewCell.h; sourceTree = "<group>"; }; 1E49A4AB161222B900463151 /* BITWebTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BITWebTableViewCell.h; sourceTree = "<group>"; };
1E49A4AC161222B900463151 /* PSWebTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PSWebTableViewCell.m; sourceTree = "<group>"; }; 1E49A4AC161222B900463151 /* BITWebTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BITWebTableViewCell.m; sourceTree = "<group>"; };
1E49A4D4161222D400463151 /* HockeySDKPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HockeySDKPrivate.h; sourceTree = "<group>"; }; 1E49A4D4161222D400463151 /* HockeySDKPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HockeySDKPrivate.h; sourceTree = "<group>"; };
1E49A4D5161222D400463151 /* HockeySDKPrivate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HockeySDKPrivate.m; sourceTree = "<group>"; }; 1E49A4D5161222D400463151 /* HockeySDKPrivate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HockeySDKPrivate.m; sourceTree = "<group>"; };
1E5954F215B6F24A00A03429 /* libHockeySDK.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libHockeySDK.a; sourceTree = BUILT_PRODUCTS_DIR; }; 1E5954F215B6F24A00A03429 /* libHockeySDK.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libHockeySDK.a; sourceTree = BUILT_PRODUCTS_DIR; };
@ -274,12 +274,12 @@
1E49A4A6161222B900463151 /* BITHockeyHelper.m */, 1E49A4A6161222B900463151 /* BITHockeyHelper.m */,
1EACC979162F041E007578C5 /* BITAttributedLabel.h */, 1EACC979162F041E007578C5 /* BITAttributedLabel.h */,
1EACC97A162F041E007578C5 /* BITAttributedLabel.m */, 1EACC97A162F041E007578C5 /* BITAttributedLabel.m */,
1E49A4A7161222B900463151 /* PSAppStoreHeader.h */, 1E49A4A7161222B900463151 /* BITAppStoreHeader.h */,
1E49A4A8161222B900463151 /* PSAppStoreHeader.m */, 1E49A4A8161222B900463151 /* BITAppStoreHeader.m */,
1E49A4A9161222B900463151 /* PSStoreButton.h */, 1E49A4A9161222B900463151 /* BITStoreButton.h */,
1E49A4AA161222B900463151 /* PSStoreButton.m */, 1E49A4AA161222B900463151 /* BITStoreButton.m */,
1E49A4AB161222B900463151 /* PSWebTableViewCell.h */, 1E49A4AB161222B900463151 /* BITWebTableViewCell.h */,
1E49A4AC161222B900463151 /* PSWebTableViewCell.m */, 1E49A4AC161222B900463151 /* BITWebTableViewCell.m */,
); );
name = Helper; name = Helper;
sourceTree = "<group>"; sourceTree = "<group>";
@ -430,9 +430,9 @@
1E49A4B5161222B900463151 /* BITHockeyBaseManagerPrivate.h in Headers */, 1E49A4B5161222B900463151 /* BITHockeyBaseManagerPrivate.h in Headers */,
1E49A4B8161222B900463151 /* BITHockeyBaseViewController.h in Headers */, 1E49A4B8161222B900463151 /* BITHockeyBaseViewController.h in Headers */,
1E49A4BE161222B900463151 /* BITHockeyHelper.h in Headers */, 1E49A4BE161222B900463151 /* BITHockeyHelper.h in Headers */,
1E49A4C4161222B900463151 /* PSAppStoreHeader.h in Headers */, 1E49A4C4161222B900463151 /* BITAppStoreHeader.h in Headers */,
1E49A4CA161222B900463151 /* PSStoreButton.h in Headers */, 1E49A4CA161222B900463151 /* BITStoreButton.h in Headers */,
1E49A4D0161222B900463151 /* PSWebTableViewCell.h in Headers */, 1E49A4D0161222B900463151 /* BITWebTableViewCell.h in Headers */,
1E49A4D8161222D400463151 /* HockeySDKPrivate.h in Headers */, 1E49A4D8161222D400463151 /* HockeySDKPrivate.h in Headers */,
1EC69F601615001500808FD9 /* BITHockeyManagerPrivate.h in Headers */, 1EC69F601615001500808FD9 /* BITHockeyManagerPrivate.h in Headers */,
1E754E5C1621FBB70070AB92 /* BITCrashManager.h in Headers */, 1E754E5C1621FBB70070AB92 /* BITCrashManager.h in Headers */,
@ -596,9 +596,9 @@
1E49A4B2161222B900463151 /* BITHockeyBaseManager.m in Sources */, 1E49A4B2161222B900463151 /* BITHockeyBaseManager.m in Sources */,
1E49A4BB161222B900463151 /* BITHockeyBaseViewController.m in Sources */, 1E49A4BB161222B900463151 /* BITHockeyBaseViewController.m in Sources */,
1E49A4C1161222B900463151 /* BITHockeyHelper.m in Sources */, 1E49A4C1161222B900463151 /* BITHockeyHelper.m in Sources */,
1E49A4C7161222B900463151 /* PSAppStoreHeader.m in Sources */, 1E49A4C7161222B900463151 /* BITAppStoreHeader.m in Sources */,
1E49A4CD161222B900463151 /* PSStoreButton.m in Sources */, 1E49A4CD161222B900463151 /* BITStoreButton.m in Sources */,
1E49A4D3161222B900463151 /* PSWebTableViewCell.m in Sources */, 1E49A4D3161222B900463151 /* BITWebTableViewCell.m in Sources */,
1E49A4DB161222D400463151 /* HockeySDKPrivate.m in Sources */, 1E49A4DB161222D400463151 /* HockeySDKPrivate.m in Sources */,
1E754E5D1621FBB70070AB92 /* BITCrashManager.m in Sources */, 1E754E5D1621FBB70070AB92 /* BITCrashManager.m in Sources */,
1E754E611621FBB70070AB92 /* BITCrashReportTextFormatter.m in Sources */, 1E754E611621FBB70070AB92 /* BITCrashReportTextFormatter.m in Sources */,