Merge branch 'mkirk/bordered-avatar'

pull/1/head
Michael Kirk 8 years ago
commit ced9125303

@ -1,5 +1,6 @@
// Created by Michael Kirk on 9/26/16. //
// Copyright © 2016 Open Whisper Systems. All rights reserved. // Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -9,7 +10,9 @@ NS_ASSUME_NONNULL_BEGIN
@interface OWSAvatarBuilder : NSObject @interface OWSAvatarBuilder : NSObject
+ (UIImage *)buildImageForThread:(TSThread *)thread contactsManager:(OWSContactsManager *)contactsManager; + (UIImage *)buildImageForThread:(TSThread *)thread
contactsManager:(OWSContactsManager *)contactsManager
diameter:(NSUInteger)diameter;
- (nullable UIImage *)buildSavedImage; - (nullable UIImage *)buildSavedImage;
- (UIImage *)buildDefaultImage; - (UIImage *)buildDefaultImage;

@ -1,5 +1,6 @@
// Created by Michael Kirk on 9/26/16. //
// Copyright © 2016 Open Whisper Systems. All rights reserved. // Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "OWSAvatarBuilder.h" #import "OWSAvatarBuilder.h"
#import "OWSContactAvatarBuilder.h" #import "OWSContactAvatarBuilder.h"
@ -11,12 +12,13 @@ NS_ASSUME_NONNULL_BEGIN
@implementation OWSAvatarBuilder @implementation OWSAvatarBuilder
+ (UIImage *)buildImageForThread:(TSThread *)thread contactsManager:(OWSContactsManager *)contactsManager + (UIImage *)buildImageForThread:(TSThread *)thread
contactsManager:(OWSContactsManager *)contactsManager
diameter:(NSUInteger)diameter
{ {
OWSAvatarBuilder *avatarBuilder; OWSAvatarBuilder *avatarBuilder;
if ([thread isKindOfClass:[TSContactThread class]]) { if ([thread isKindOfClass:[TSContactThread class]]) {
avatarBuilder = avatarBuilder = [[OWSContactAvatarBuilder alloc] initWithThread:(TSContactThread *)thread contactsManager:contactsManager diameter:diameter];
[[OWSContactAvatarBuilder alloc] initWithThread:(TSContactThread *)thread contactsManager:contactsManager];
} else if ([thread isKindOfClass:[TSGroupThread class]]) { } else if ([thread isKindOfClass:[TSGroupThread class]]) {
avatarBuilder = [[OWSGroupAvatarBuilder alloc] initWithThread:(TSGroupThread *)thread]; avatarBuilder = [[OWSGroupAvatarBuilder alloc] initWithThread:(TSGroupThread *)thread];
} else { } else {

@ -1,5 +1,6 @@
// Created by Michael Kirk on 9/22/16. //
// Copyright © 2016 Open Whisper Systems. All rights reserved. // Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "OWSAvatarBuilder.h" #import "OWSAvatarBuilder.h"
@ -12,9 +13,12 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithContactId:(NSString *)contactId - (instancetype)initWithContactId:(NSString *)contactId
name:(NSString *)name name:(NSString *)name
contactsManager:(OWSContactsManager *)contactsManager; contactsManager:(OWSContactsManager *)contactsManager
diameter:(NSUInteger)diameter;
- (instancetype)initWithThread:(TSContactThread *)thread contactsManager:(OWSContactsManager *)contactsManager; - (instancetype)initWithThread:(TSContactThread *)thread
contactsManager:(OWSContactsManager *)contactsManager
diameter:(NSUInteger)diameter;
@end @end

@ -1,5 +1,6 @@
// Created by Michael Kirk on 9/22/16. //
// Copyright © 2016 Open Whisper Systems. All rights reserved. // Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "OWSContactAvatarBuilder.h" #import "OWSContactAvatarBuilder.h"
#import "OWSContactsManager.h" #import "OWSContactsManager.h"
@ -17,6 +18,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly) OWSContactsManager *contactsManager; @property (nonatomic, readonly) OWSContactsManager *contactsManager;
@property (nonatomic, readonly) NSString *signalId; @property (nonatomic, readonly) NSString *signalId;
@property (nonatomic, readonly) NSString *contactName; @property (nonatomic, readonly) NSString *contactName;
@property (nonatomic, readonly) NSUInteger diameter;
@end @end
@ -25,23 +27,26 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithContactId:(NSString *)contactId - (instancetype)initWithContactId:(NSString *)contactId
name:(NSString *)name name:(NSString *)name
contactsManager:(OWSContactsManager *)contactsManager contactsManager:(OWSContactsManager *)contactsManager
diameter:(NSUInteger)diameter
{ {
self = [super init]; self = [super init];
if (!self) { if (!self) {
return self; return self;
} }
_signalId = contactId; _signalId = contactId;
_contactName = name; _contactName = name;
_contactsManager = contactsManager; _contactsManager = contactsManager;
_diameter = diameter;
return self; return self;
} }
- (instancetype)initWithThread:(TSContactThread *)thread
- (instancetype)initWithThread:(TSContactThread *)thread contactsManager:(OWSContactsManager *)contactsManager contactsManager:(OWSContactsManager *)contactsManager
diameter:(NSUInteger)diameter
{ {
return [self initWithContactId:thread.contactIdentifier name:thread.name contactsManager:contactsManager]; return [self initWithContactId:thread.contactIdentifier name:thread.name contactsManager:contactsManager diameter:diameter];
} }
- (nullable UIImage *)buildSavedImage - (nullable UIImage *)buildSavedImage
@ -51,7 +56,8 @@ NS_ASSUME_NONNULL_BEGIN
- (UIImage *)buildDefaultImage - (UIImage *)buildDefaultImage
{ {
UIImage *cachedAvatar = [self.contactsManager.avatarCache objectForKey:self.signalId]; NSString *cacheKey = [NSString stringWithFormat:@"signalId:%@:diamater:%lu", self.signalId, (unsigned long)self.diameter];
UIImage *cachedAvatar = [self.contactsManager.avatarCache objectForKey:cacheKey];
if (cachedAvatar) { if (cachedAvatar) {
return cachedAvatar; return cachedAvatar;
} }
@ -82,12 +88,13 @@ NS_ASSUME_NONNULL_BEGIN
[initials appendString:@"#"]; [initials appendString:@"#"];
} }
CGFloat fontSize = (CGFloat)self.diameter / 2.8;
UIColor *backgroundColor = [UIColor backgroundColorForContact:self.signalId]; UIColor *backgroundColor = [UIColor backgroundColorForContact:self.signalId];
UIImage *image = [[JSQMessagesAvatarImageFactory avatarImageWithUserInitials:initials UIImage *image = [[JSQMessagesAvatarImageFactory avatarImageWithUserInitials:initials
backgroundColor:backgroundColor backgroundColor:backgroundColor
textColor:[UIColor whiteColor] textColor:[UIColor whiteColor]
font:[UIFont ows_boldFontWithSize:36.0] font:[UIFont ows_boldFontWithSize:fontSize]
diameter:100] avatarImage]; diameter:self.diameter] avatarImage];
[self.contactsManager.avatarCache setObject:image forKey:self.signalId]; [self.contactsManager.avatarCache setObject:image forKey:self.signalId];
return image; return image;
} }

@ -147,7 +147,7 @@ class CallViewController: UIViewController, CallObserver, CallServiceObserver, R
createViews() createViews()
contactNameLabel.text = contactsManager.displayName(forPhoneIdentifier: thread.contactIdentifier()) contactNameLabel.text = contactsManager.displayName(forPhoneIdentifier: thread.contactIdentifier())
contactAvatarView.image = OWSAvatarBuilder.buildImage(for: thread, contactsManager: contactsManager) contactAvatarView.image = OWSAvatarBuilder.buildImage(for: thread, contactsManager: contactsManager, diameter:400)
assert(call != nil) assert(call != nil)
// Subscribe for future call updates // Subscribe for future call updates

@ -2,13 +2,13 @@
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2017 Open Whisper Systems. All rights reserved.
// //
#import <UIKit/UIKit.h>
#import "TSThread.h" #import "TSThread.h"
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@class Contact; @class Contact;
@class OWSContactsManager; @class OWSContactsManager;
@class AvatarImageView;
typedef enum : NSUInteger { kArchiveState = 0, kInboxState = 1 } CellState; typedef enum : NSUInteger { kArchiveState = 0, kInboxState = 1 } CellState;
@ -16,7 +16,7 @@ typedef enum : NSUInteger { kArchiveState = 0, kInboxState = 1 } CellState;
@property (nonatomic) IBOutlet UILabel *nameLabel; @property (nonatomic) IBOutlet UILabel *nameLabel;
@property (nonatomic) IBOutlet UILabel *snippetLabel; @property (nonatomic) IBOutlet UILabel *snippetLabel;
@property (nonatomic) IBOutlet UIImageView *contactPictureView; @property (nonatomic) IBOutlet AvatarImageView *contactPictureView;
@property (nonatomic) IBOutlet UILabel *timeLabel; @property (nonatomic) IBOutlet UILabel *timeLabel;
@property (nonatomic) IBOutlet UIView *contentContainerView; @property (nonatomic) IBOutlet UIView *contentContainerView;
@property (nonatomic) IBOutlet UIView *messageCounter; @property (nonatomic) IBOutlet UIView *messageCounter;

@ -24,6 +24,8 @@ NS_ASSUME_NONNULL_BEGIN
#define DATE_LABEL_SIZE 13 #define DATE_LABEL_SIZE 13
#define SWIPE_ARCHIVE_OFFSET -50 #define SWIPE_ARCHIVE_OFFSET -50
const NSUInteger kContactPictureViewDiameter = 52;
@interface InboxTableViewCell () @interface InboxTableViewCell ()
@property (nonatomic) NSUInteger unreadMessages; @property (nonatomic) NSUInteger unreadMessages;
@ -120,7 +122,6 @@ NS_ASSUME_NONNULL_BEGIN
self.snippetLabel.attributedText = snippetText; self.snippetLabel.attributedText = snippetText;
self.timeLabel.attributedText = attributedDate; self.timeLabel.attributedText = attributedDate;
self.contactPictureView.image = nil; self.contactPictureView.image = nil;
[UIUtil applyRoundedBorderToImageView:_contactPictureView];
self.separatorInset = UIEdgeInsetsMake(0, _contactPictureView.frame.size.width * 1.5f, 0, 0); self.separatorInset = UIEdgeInsetsMake(0, _contactPictureView.frame.size.width * 1.5f, 0, 0);
@ -133,7 +134,9 @@ NS_ASSUME_NONNULL_BEGIN
NSString *threadIdCopy = thread.uniqueId; NSString *threadIdCopy = thread.uniqueId;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage *avatar = [OWSAvatarBuilder buildImageForThread:thread contactsManager:contactsManager]; UIImage *avatar = [OWSAvatarBuilder buildImageForThread:thread
contactsManager:contactsManager
diameter:kContactPictureViewDiameter];
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
if ([_threadId isEqualToString:threadIdCopy]) { if ([_threadId isEqualToString:threadIdCopy]) {
self.contactPictureView.image = avatar; self.contactPictureView.image = avatar;

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="15G1217" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait"> <device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/> <adaptation id="fullscreen"/>
</device> </device>
<dependencies> <dependencies>
<deployment identifier="iOS"/> <deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
<capability name="Aspect ratio constraints" minToolsVersion="5.1"/> <capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
@ -16,15 +16,16 @@
<rect key="frame" x="0.0" y="0.0" width="400" height="72"/> <rect key="frame" x="0.0" y="0.0" width="400" height="72"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<tableViewCellContentView key="contentView" multipleTouchEnabled="YES" contentMode="center" tableViewCell="axX-Rb-kiK" id="BRG-hJ-lRa"> <tableViewCellContentView key="contentView" multipleTouchEnabled="YES" contentMode="center" tableViewCell="axX-Rb-kiK" id="BRG-hJ-lRa">
<rect key="frame" x="0.0" y="0.0" width="400" height="71"/> <rect key="frame" x="0.0" y="0.0" width="400" height="71.5"/>
<autoresizingMask key="autoresizingMask" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxY="YES"/>
<subviews> <subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kq8-RD-txC" userLabel="Container View"> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kq8-RD-txC" userLabel="Container View">
<rect key="frame" x="0.0" y="0.0" width="400" height="72"/> <rect key="frame" x="0.0" y="0.0" width="400" height="47"/>
<subviews> <subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="p9o-x6-nT5"> <imageView userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="p9o-x6-nT5" customClass="AvatarImageView" customModule="Signal" customModuleProvider="target">
<rect key="frame" x="10" y="10" width="52" height="53"/> <rect key="frame" x="10" y="10" width="52" height="52"/>
<constraints> <constraints>
<constraint firstAttribute="width" secondItem="p9o-x6-nT5" secondAttribute="height" multiplier="1:1" id="IjZ-Ac-GiV"/>
<constraint firstAttribute="width" constant="52" id="mb7-1o-58k"/> <constraint firstAttribute="width" constant="52" id="mb7-1o-58k"/>
</constraints> </constraints>
</imageView> </imageView>
@ -54,7 +55,7 @@
</constraints> </constraints>
</view> </view>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="mfN-2A-QxN"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="mfN-2A-QxN">
<rect key="frame" x="75" y="6" width="236" height="25"/> <rect key="frame" x="75" y="6" width="236" height="0.0"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="16"/> <fontDescription key="fontDescription" type="boldSystem" pointSize="16"/>
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/> <color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>

@ -26,6 +26,8 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
const NSUInteger kNewGroupViewControllerAvatarWidth = 68;
@interface NewGroupViewController () <UIImagePickerControllerDelegate, @interface NewGroupViewController () <UIImagePickerControllerDelegate,
UITextFieldDelegate, UITextFieldDelegate,
ContactsViewHelperDelegate, ContactsViewHelperDelegate,
@ -39,7 +41,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly) GroupViewHelper *groupViewHelper; @property (nonatomic, readonly) GroupViewHelper *groupViewHelper;
@property (nonatomic, readonly) OWSTableViewController *tableViewController; @property (nonatomic, readonly) OWSTableViewController *tableViewController;
@property (nonatomic, readonly) UIImageView *avatarView; @property (nonatomic, readonly) AvatarImageView *avatarView;
@property (nonatomic, readonly) UITextField *groupNameTextField; @property (nonatomic, readonly) UITextField *groupNameTextField;
@property (nonatomic, nullable) UIImage *groupAvatar; @property (nonatomic, nullable) UIImage *groupAvatar;
@ -134,18 +136,14 @@ NS_ASSUME_NONNULL_BEGIN
[threadInfoView autoPinWidthToSuperviewWithMargin:16.f]; [threadInfoView autoPinWidthToSuperviewWithMargin:16.f];
[threadInfoView autoPinHeightToSuperviewWithMargin:16.f]; [threadInfoView autoPinHeightToSuperviewWithMargin:16.f];
const CGFloat kAvatarSize = 68.f; AvatarImageView *avatarView = [AvatarImageView new];
UIImageView *avatarView = [UIImageView new];
_avatarView = avatarView; _avatarView = avatarView;
avatarView.layer.borderColor = UIColor.clearColor.CGColor;
avatarView.layer.masksToBounds = YES;
avatarView.layer.cornerRadius = kAvatarSize / 2.0f;
avatarView.contentMode = UIViewContentModeScaleAspectFill;
[threadInfoView addSubview:avatarView]; [threadInfoView addSubview:avatarView];
[avatarView autoVCenterInSuperview]; [avatarView autoVCenterInSuperview];
[avatarView autoPinEdgeToSuperviewEdge:ALEdgeLeft]; [avatarView autoPinEdgeToSuperviewEdge:ALEdgeLeft];
[avatarView autoSetDimension:ALDimensionWidth toSize:kAvatarSize]; [avatarView autoSetDimension:ALDimensionWidth toSize:kNewGroupViewControllerAvatarWidth];
[avatarView autoSetDimension:ALDimensionHeight toSize:kAvatarSize]; [avatarView autoSetDimension:ALDimensionHeight toSize:kNewGroupViewControllerAvatarWidth];
[self updateAvatarView]; [self updateAvatarView];
UITextField *groupNameTextField = [UITextField new]; UITextField *groupNameTextField = [UITextField new];
@ -494,13 +492,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)updateAvatarView - (void)updateAvatarView
{ {
UIImage *image = (self.groupAvatar ?: [UIImage imageNamed:@"empty-group-avatar"]); self.avatarView.image = (self.groupAvatar ?: [UIImage imageNamed:@"empty-group-avatar"]);
OWSAssert(image);
self.avatarView.image = image;
self.avatarView.layer.borderColor = [[UIColor lightGrayColor] CGColor];
self.avatarView.layer.borderWidth = 0.5f;
self.avatarView.contentMode = UIViewContentModeScaleAspectFill;
} }
#pragma mark - Event Handling #pragma mark - Event Handling

@ -536,15 +536,13 @@ NS_ASSUME_NONNULL_BEGIN
[threadInfoView autoPinWidthToSuperviewWithMargin:16.f]; [threadInfoView autoPinWidthToSuperviewWithMargin:16.f];
[threadInfoView autoPinHeightToSuperviewWithMargin:16.f]; [threadInfoView autoPinHeightToSuperviewWithMargin:16.f];
UIImage *avatar = [OWSAvatarBuilder buildImageForThread:self.thread contactsManager:self.contactsManager]; const NSUInteger kAvatarSize = 68;
UIImage *avatar =
[OWSAvatarBuilder buildImageForThread:self.thread contactsManager:self.contactsManager diameter:kAvatarSize];
OWSAssert(avatar); OWSAssert(avatar);
const CGFloat kAvatarSize = 68.f;
UIImageView *avatarView = [[UIImageView alloc] initWithImage:avatar]; AvatarImageView *avatarView = [[AvatarImageView alloc] initWithImage:avatar];
_avatarView = avatarView; _avatarView = avatarView;
avatarView.layer.borderColor = UIColor.clearColor.CGColor;
avatarView.layer.masksToBounds = YES;
avatarView.layer.cornerRadius = kAvatarSize / 2.0f;
avatarView.contentMode = UIViewContentModeScaleAspectFill;
[threadInfoView addSubview:avatarView]; [threadInfoView addSubview:avatarView];
[avatarView autoVCenterInSuperview]; [avatarView autoVCenterInSuperview];
[avatarView autoPinEdgeToSuperviewEdge:ALEdgeLeft]; [avatarView autoPinEdgeToSuperviewEdge:ALEdgeLeft];

@ -40,7 +40,7 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly) GroupViewHelper *groupViewHelper; @property (nonatomic, readonly) GroupViewHelper *groupViewHelper;
@property (nonatomic, readonly) OWSTableViewController *tableViewController; @property (nonatomic, readonly) OWSTableViewController *tableViewController;
@property (nonatomic, readonly) UIImageView *avatarView; @property (nonatomic, readonly) AvatarImageView *avatarView;
@property (nonatomic, readonly) UITextField *groupNameTextField; @property (nonatomic, readonly) UITextField *groupNameTextField;
@property (nonatomic, nullable) UIImage *groupAvatar; @property (nonatomic, nullable) UIImage *groupAvatar;
@ -180,12 +180,9 @@ NS_ASSUME_NONNULL_BEGIN
[threadInfoView autoPinHeightToSuperviewWithMargin:16.f]; [threadInfoView autoPinHeightToSuperviewWithMargin:16.f];
const CGFloat kAvatarSize = 68.f; const CGFloat kAvatarSize = 68.f;
UIImageView *avatarView = [UIImageView new]; AvatarImageView *avatarView = [AvatarImageView new];
_avatarView = avatarView; _avatarView = avatarView;
avatarView.layer.borderColor = UIColor.clearColor.CGColor;
avatarView.layer.masksToBounds = YES;
avatarView.layer.cornerRadius = kAvatarSize / 2.0f;
avatarView.contentMode = UIViewContentModeScaleAspectFill;
[threadInfoView addSubview:avatarView]; [threadInfoView addSubview:avatarView];
[avatarView autoVCenterInSuperview]; [avatarView autoVCenterInSuperview];
[avatarView autoPinEdgeToSuperviewEdge:ALEdgeLeft]; [avatarView autoPinEdgeToSuperviewEdge:ALEdgeLeft];
@ -403,13 +400,7 @@ NS_ASSUME_NONNULL_BEGIN
- (void)updateAvatarView - (void)updateAvatarView
{ {
UIImage *image = (self.groupAvatar ?: [UIImage imageNamed:@"empty-group-avatar"]); self.avatarView.image = (self.groupAvatar ?: [UIImage imageNamed:@"empty-group-avatar"]);
OWSAssert(image);
self.avatarView.image = image;
self.avatarView.layer.borderColor = [[UIColor lightGrayColor] CGColor];
self.avatarView.layer.borderWidth = 0.5f;
self.avatarView.contentMode = UIViewContentModeScaleAspectFill;
} }
#pragma mark - Event Handling #pragma mark - Event Handling

@ -153,7 +153,7 @@
drawRect.origin.x = 0; drawRect.origin.x = 0;
drawRect.size.width = dstSize.width; drawRect.size.width = dstSize.width;
drawRect.size.height = dstSize.width * srcSize.height / srcSize.width; drawRect.size.height = dstSize.width * srcSize.height / srcSize.width;
OWSAssert(drawRect.size.height > dstSize.height); OWSAssert(drawRect.size.height >= dstSize.height);
drawRect.origin.y = (drawRect.size.height - dstSize.height) * -0.5f; drawRect.origin.y = (drawRect.size.height - dstSize.height) * -0.5f;
} }

@ -1,14 +1,41 @@
// Created by Michael Kirk on 12/11/16. //
// Copyright © 2016 Open Whisper Systems. All rights reserved. // Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
import UIKit import UIKit
@IBDesignable
class AvatarImageView: UIImageView { class AvatarImageView: UIImageView {
override func layoutSubviews() { init() {
super.init(frame: CGRect.zero)
self.configureView()
}
override init(frame: CGRect) {
super.init(frame: frame)
self.configureView()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.configureView()
}
override init(image: UIImage?) {
super.init(image: image)
self.configureView()
}
func configureView() {
self.layer.minificationFilter = kCAFilterTrilinear
self.layer.magnificationFilter = kCAFilterTrilinear
self.layer.borderWidth = 0.5
self.layer.masksToBounds = true self.layer.masksToBounds = true
self.layer.cornerRadius = self.frame.size.width / 2 self.contentMode = .scaleToFill
} }
override func layoutSubviews() {
self.layer.borderColor = UIColor.black.cgColor.copy(alpha: 0.15)
self.layer.cornerRadius = self.frame.size.width / 2
}
} }

@ -60,9 +60,11 @@ class ContactCell: UITableViewCell {
contactIdForDeterminingBackgroundColor = contact.fullName contactIdForDeterminingBackgroundColor = contact.fullName
} }
let kAvatarWidth: UInt = 40
let avatarBuilder = OWSContactAvatarBuilder(contactId:contactIdForDeterminingBackgroundColor, let avatarBuilder = OWSContactAvatarBuilder(contactId:contactIdForDeterminingBackgroundColor,
name:contact.fullName, name:contact.fullName,
contactsManager:contactsManager) contactsManager:contactsManager,
diameter: kAvatarWidth)
self.contactImageView?.image = avatarBuilder.buildDefaultImage() self.contactImageView?.image = avatarBuilder.buildDefaultImage()
} else { } else {
self.contactImageView?.image = contact.image self.contactImageView?.image = contact.image

@ -6,6 +6,7 @@
#import "Environment.h" #import "Environment.h"
#import "OWSContactAvatarBuilder.h" #import "OWSContactAvatarBuilder.h"
#import "OWSContactsManager.h" #import "OWSContactsManager.h"
#import "Signal-Swift.h"
#import "UIFont+OWS.h" #import "UIFont+OWS.h"
#import "UIUtil.h" #import "UIUtil.h"
#import "UIView+OWS.h" #import "UIView+OWS.h"
@ -16,6 +17,7 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
NSString *const kContactsTable_CellReuseIdentifier = @"kContactsTable_CellReuseIdentifier"; NSString *const kContactsTable_CellReuseIdentifier = @"kContactsTable_CellReuseIdentifier";
const NSUInteger kContactTableViewCellAvatarSize = 40;
@interface ContactTableViewCell () @interface ContactTableViewCell ()
@ -51,15 +53,7 @@ NSString *const kContactsTable_CellReuseIdentifier = @"kContactsTable_CellReuseI
- (void)configureProgrammatically - (void)configureProgrammatically
{ {
const CGFloat kAvatarSize = 40.f; _avatarView = [AvatarImageView new];
_avatarView = [UIImageView new];
_avatarView.image = [UIImage imageNamed:@"empty-group-avatar"];
_avatarView.contentMode = UIViewContentModeScaleToFill;
// applyRoundedBorderToImageView requires the avatar to have
// the correct size.
_avatarView.frame = CGRectMake(0, 0, kAvatarSize, kAvatarSize);
_avatarView.layer.minificationFilter = kCAFilterTrilinear;
_avatarView.layer.magnificationFilter = kCAFilterTrilinear;
[self.contentView addSubview:_avatarView]; [self.contentView addSubview:_avatarView];
_nameLabel = [UILabel new]; _nameLabel = [UILabel new];
@ -70,8 +64,8 @@ NSString *const kContactsTable_CellReuseIdentifier = @"kContactsTable_CellReuseI
[_avatarView autoVCenterInSuperview]; [_avatarView autoVCenterInSuperview];
[_avatarView autoPinEdgeToSuperviewEdge:ALEdgeLeft withInset:ScaleFromIPhone5To7Plus(14.f, 20.f)]; [_avatarView autoPinEdgeToSuperviewEdge:ALEdgeLeft withInset:ScaleFromIPhone5To7Plus(14.f, 20.f)];
[_avatarView autoSetDimension:ALDimensionWidth toSize:kAvatarSize]; [_avatarView autoSetDimension:ALDimensionWidth toSize:kContactTableViewCellAvatarSize];
[_avatarView autoSetDimension:ALDimensionHeight toSize:kAvatarSize]; [_avatarView autoSetDimension:ALDimensionHeight toSize:kContactTableViewCellAvatarSize];
[_nameLabel autoPinEdgeToSuperviewEdge:ALEdgeRight]; [_nameLabel autoPinEdgeToSuperviewEdge:ALEdgeRight];
[_nameLabel autoPinEdgeToSuperviewEdge:ALEdgeTop]; [_nameLabel autoPinEdgeToSuperviewEdge:ALEdgeTop];
@ -117,9 +111,10 @@ NSString *const kContactsTable_CellReuseIdentifier = @"kContactsTable_CellReuseI
self.accessoryView = blockedLabel; self.accessoryView = blockedLabel;
} }
self.nameLabel.attributedText = attributedText; self.nameLabel.attributedText = attributedText;
self.avatarView.image = self.avatarView.image = [[[OWSContactAvatarBuilder alloc] initWithContactId:recipientId
[[[OWSContactAvatarBuilder alloc] initWithContactId:recipientId name:avatarName contactsManager:contactsManager] name:avatarName
build]; contactsManager:contactsManager
diameter:kContactTableViewCellAvatarSize] build];
// Force layout, since imageView isn't being initally rendered on App Store optimized build. // Force layout, since imageView isn't being initally rendered on App Store optimized build.
[self layoutSubviews]; [self layoutSubviews];
@ -141,18 +136,14 @@ NSString *const kContactsTable_CellReuseIdentifier = @"kContactsTable_CellReuseI
}]; }];
self.nameLabel.attributedText = attributedText; self.nameLabel.attributedText = attributedText;
self.avatarView.image = [OWSAvatarBuilder buildImageForThread:thread contactsManager:contactsManager]; self.avatarView.image = [OWSAvatarBuilder buildImageForThread:thread
contactsManager:contactsManager
diameter:kContactTableViewCellAvatarSize];
// Force layout, since imageView isn't being initally rendered on App Store optimized build. // Force layout, since imageView isn't being initally rendered on App Store optimized build.
[self layoutSubviews]; [self layoutSubviews];
} }
- (void)layoutSubviews
{
[super layoutSubviews];
[UIUtil applyRoundedBorderToImageView:self.avatarView];
}
- (void)prepareForReuse - (void)prepareForReuse
{ {
self.accessoryMessage = nil; self.accessoryMessage = nil;

Loading…
Cancel
Save