Merge pull request #39 from MessageKit/AvatarViewStruct

Avatar view struct
This commit is contained in:
Steven Deutsch
2017-08-07 21:50:03 -05:00
committed by GitHub
20 changed files with 233 additions and 297 deletions
@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
37D3EAC41F390E5F00DD6A55 /* SampleData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37D3EAC31F390E5F00DD6A55 /* SampleData.swift */; };
882B5E811CF7D53600B6E160 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 882B5E781CF7D53600B6E160 /* AppDelegate.swift */; };
882B5E821CF7D53600B6E160 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 882B5E791CF7D53600B6E160 /* Assets.xcassets */; };
882B5E831CF7D53600B6E160 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 882B5E7A1CF7D53600B6E160 /* LaunchScreen.storyboard */; };
@@ -74,6 +75,8 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
37D3EAC31F390E5F00DD6A55 /* SampleData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SampleData.swift; sourceTree = "<group>"; };
37F8BCD41F38F3A8003C12C2 /* Avatar.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; name = Avatar.playground; path = Playgrounds/Avatar.playground; sourceTree = "<group>"; };
882B5E331CF7D4B900B6E160 /* ChatExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ChatExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
882B5E491CF7D4B900B6E160 /* ChatExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ChatExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
882B5E541CF7D4B900B6E160 /* ChatExampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ChatExampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -145,7 +148,9 @@
children = (
882B5E781CF7D53600B6E160 /* AppDelegate.swift */,
B0655A321F23E90800542A83 /* ConversationViewController.swift */,
37D3EAC31F390E5F00DD6A55 /* SampleData.swift */,
882B5E7E1CF7D53600B6E160 /* InboxViewController.swift */,
37F8BCD41F38F3A8003C12C2 /* Avatar.playground */,
B096438A1F288D47004D0129 /* MockMessage.swift */,
882B5E801CF7D53600B6E160 /* SettingsViewController.swift */,
882B5E791CF7D53600B6E160 /* Assets.xcassets */,
@@ -249,7 +254,7 @@
attributes = {
LastSwiftUpdateCheck = 0730;
LastUpgradeCheck = 0810;
ORGANIZATIONNAME = "Hexed Bits";
ORGANIZATIONNAME = MessageKit;
TargetAttributes = {
882B5E321CF7D4B900B6E160 = {
CreatedOnToolsVersion = 7.3.1;
@@ -342,6 +347,7 @@
buildActionMask = 2147483647;
files = (
882B5E871CF7D53600B6E160 /* SettingsViewController.swift in Sources */,
37D3EAC41F390E5F00DD6A55 /* SampleData.swift in Sources */,
B096438B1F288D47004D0129 /* MockMessage.swift in Sources */,
882B5E811CF7D53600B6E160 /* AppDelegate.swift in Sources */,
B0655A331F23E90800542A83 /* ConversationViewController.swift in Sources */,
@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "NiceSelfi.jpg",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 40 KiB

+4 -91
View File
@@ -1,17 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12120" systemVersion="16F73" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="49e-Tb-3d3">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="qIf-zY-DwN">
<device id="retina4_7" orientation="portrait">
<adaptation id="fullscreen"/>
</device>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--Inbox-->
<scene sceneID="bfl-pY-VjE">
<objects>
<placeholder placeholderIdentifier="IBFirstResponder" id="6WU-8e-ICx" userLabel="First Responder" sceneMemberID="firstResponder"/>
<tableViewController title="Inbox" clearsSelectionOnViewWillAppear="NO" id="Pev-jS-Pyn" customClass="InboxViewController" customModule="ChatExample" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" id="hyI-h1-cQJ">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
@@ -25,9 +26,6 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</tableViewCellContentView>
<connections>
<segue destination="liE-CN-1Q3" kind="show" id="4X0-1b-yom"/>
</connections>
</tableViewCell>
</prototypes>
<connections>
@@ -35,30 +33,11 @@
<outlet property="delegate" destination="Pev-jS-Pyn" id="uuf-Ll-gIS"/>
</connections>
</tableView>
<navigationItem key="navigationItem" title="Inbox" id="pM3-Dy-Tq2"/>
<navigationItem key="navigationItem" title="MessageKit" id="pM3-Dy-Tq2"/>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="6WU-8e-ICx" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1067" y="-252"/>
</scene>
<!--Conversation View Controller-->
<scene sceneID="DNz-5r-g7p">
<objects>
<viewController id="liE-CN-1Q3" customClass="ConversationViewController" customModule="ChatExample" customModuleProvider="target" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="X1Z-Rt-oge"/>
<viewControllerLayoutGuide type="bottom" id="jTg-1r-P9t"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="YUH-C1-4hJ">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="wuy-lF-2nR" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1817" y="-249"/>
</scene>
<!--Item-->
<scene sceneID="RIX-3V-AwK">
<objects>
@@ -76,71 +55,5 @@
</objects>
<point key="canvasLocation" x="338" y="-252"/>
</scene>
<!--Settings-->
<scene sceneID="pVX-a9-SMa">
<objects>
<tableViewController title="Settings" id="72O-av-jde" customClass="SettingsViewController" customModule="ChatExample" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" id="lpF-QO-eb8">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" reuseIdentifier="cell" id="L7s-TD-5nE">
<rect key="frame" x="0.0" y="56" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="L7s-TD-5nE" id="3Kc-oF-DKn">
<rect key="frame" x="0.0" y="0.0" width="375" height="43"/>
<autoresizingMask key="autoresizingMask"/>
</tableViewCellContentView>
</tableViewCell>
</prototypes>
<connections>
<outlet property="dataSource" destination="72O-av-jde" id="mYY-FH-eZJ"/>
<outlet property="delegate" destination="72O-av-jde" id="JHI-G3-2OK"/>
</connections>
</tableView>
<tabBarItem key="tabBarItem" title="Settings" id="LAD-r6-lZO"/>
<navigationItem key="navigationItem" title="Settings" id="CYW-K0-e3l"/>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="VzG-Xy-fQS" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1067" y="465"/>
</scene>
<!--Settings-->
<scene sceneID="5t5-pv-EFo">
<objects>
<navigationController title="Settings" id="HsT-8D-kIY" sceneMemberID="viewController">
<tabBarItem key="tabBarItem" title="Settings" id="nLg-o4-bd0"/>
<navigationBar key="navigationBar" contentMode="scaleToFill" id="6gh-G8-7aR">
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<connections>
<segue destination="72O-av-jde" kind="relationship" relationship="rootViewController" id="tOk-cH-lDJ"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="f8P-CH-n1o" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="338" y="465"/>
</scene>
<!--Tab Bar Controller-->
<scene sceneID="yl2-sM-qoP">
<objects>
<tabBarController id="49e-Tb-3d3" sceneMemberID="viewController">
<nil key="simulatedBottomBarMetrics"/>
<tabBar key="tabBar" contentMode="scaleToFill" id="W28-zg-YXA">
<rect key="frame" x="0.0" y="975" width="768" height="49"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" flexibleMinY="YES"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
</tabBar>
<connections>
<segue destination="qIf-zY-DwN" kind="relationship" relationship="viewControllers" id="srD-y8-X25"/>
<segue destination="HsT-8D-kIY" kind="relationship" relationship="viewControllers" id="MuA-na-hKR"/>
</connections>
</tabBarController>
<placeholder placeholderIdentifier="IBFirstResponder" id="HuB-VB-40B" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-496" y="72"/>
</scene>
</scenes>
</document>
@@ -27,66 +27,17 @@ import MessageKit
class ConversationViewController: MessagesViewController {
var messages: [MessageType] = []
var messageList: [MockMessage] = []
override func viewDidLoad() {
super.viewDidLoad()
addSampleData()
messageList = SampleData().getMessages()
messagesCollectionView.messagesDataSource = self
messagesCollectionView.messageCellDelegate = self
messagesCollectionView.messagesLayoutDelegate = self
messageInputBar.delegate = self
tabBarController?.tabBar.isHidden = true
}
func addSampleData() {
let sender1 = Sender(id: "123456", displayName: "Bobby")
let sender2 = Sender(id: "654321", displayName: "Steven")
let sender3 = Sender(id: "777999", displayName: "Omar")
let msg1 = "Lorem ipsum dolor sit amet, consectetur adipiscing elit." +
"Pellentesque venenatis, ante et hendrerit rutrum" +
"Quam erat vehicula metus, et condimentum ante tellus augue."
let msg2 = "Cras efficitur bibendum mauris sed ultrices." +
"Phasellus tellus nisl, ullamcorper quis erat."
let msg3 = "Maecenas."
let msg4 = "Pellentesque venenatis, ante et hendrerit rutrum" +
"Quam erat vehicula metus, et condimentum ante tellus augue."
let msg5 = "Lorem ipsum dolor sit amet, consectetur adipiscing elit." +
"Pellentesque venenatis, ante et hendrerit rutrum" +
"Quam erat vehicula metus, et condimentum ante tellus augue."
messages.append(MockMessage(text: msg2, sender: sender2, id: NSUUID().uuidString))
messages.append(MockMessage(text: msg4, sender: currentSender(), id: NSUUID().uuidString))
messages.append(MockMessage(text: msg5, sender: sender3, id: NSUUID().uuidString))
messages.append(MockMessage(text: msg1, sender: currentSender(), id: NSUUID().uuidString))
messages.append(MockMessage(text: msg3, sender: sender1, id: NSUUID().uuidString))
messages.append(MockMessage(text: msg3, sender: sender1, id: NSUUID().uuidString))
messages.append(MockMessage(text: msg2, sender: sender2, id: NSUUID().uuidString))
messages.append(MockMessage(text: msg2, sender: sender2, id: NSUUID().uuidString))
messages.append(MockMessage(text: msg1, sender: currentSender(), id: NSUUID().uuidString))
messages.append(MockMessage(text: msg3, sender: sender1, id: NSUUID().uuidString))
messages.append(MockMessage(text: msg2, sender: sender2, id: NSUUID().uuidString))
messages.append(MockMessage(text: msg4, sender: currentSender(), id: NSUUID().uuidString))
messages.append(MockMessage(text: msg5, sender: sender3, id: NSUUID().uuidString))
messages.append(MockMessage(text: msg4, sender: currentSender(), id: NSUUID().uuidString))
messages.append(MockMessage(text: msg5, sender: sender3, id: NSUUID().uuidString))
messages.append(MockMessage(text: msg4, sender: currentSender(), id: NSUUID().uuidString))
messages.append(MockMessage(text: msg5, sender: sender3, id: NSUUID().uuidString))
messages.append(MockMessage(text: msg1, sender: currentSender(), id: NSUUID().uuidString))
messages.append(MockMessage(text: msg1, sender: currentSender(), id: NSUUID().uuidString))
messages.append(MockMessage(text: msg3, sender: sender1, id: NSUUID().uuidString))
}
}
// MARK: - MessagesDataSource
@@ -94,15 +45,15 @@ class ConversationViewController: MessagesViewController {
extension ConversationViewController: MessagesDataSource {
func currentSender() -> Sender {
return Sender(id: "123", displayName: "Steven")
return SampleData().getCurrentSender()
}
func numberOfMessages(in messagesCollectionView: MessagesCollectionView) -> Int {
return messages.count
return messageList.count
}
func messageForItem(at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> MessageType {
return messages[indexPath.section]
return messageList[indexPath.section]
}
}
@@ -111,9 +62,8 @@ extension ConversationViewController: MessagesDataSource {
extension ConversationViewController: MessagesDisplayDataSource {
func avatarForMessage(_ message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> AvatarView {
let image = isFromCurrentSender(message: message) ? #imageLiteral(resourceName: "Steve-Jobs") : #imageLiteral(resourceName: "Tim-Cook")
return AvatarView(image: image)
func avatarForMessage(_ message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> Avatar {
return SampleData().getAvatarFor(sender: message.sender)
}
func headerForMessage(_ message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> MessageHeaderView? {
@@ -159,13 +109,9 @@ extension ConversationViewController: MessageCellDelegate {
extension ConversationViewController: MessageInputBarDelegate {
func sendButtonPressed(sender: UIButton, textView: UITextView) {
guard let message = textView.text else { return }
messages.append(MockMessage(text: message, sender: currentSender(), id: NSUUID().uuidString))
messageList.append(MockMessage(text: message, sender: currentSender(), messageId: UUID().uuidString))
messagesCollectionView.reloadData()
}
}
+18 -3
View File
@@ -27,18 +27,33 @@ import MessageKit
final class InboxViewController: UITableViewController {
let cells = ["Test", "Settings"]
override func viewDidLoad() {
super.viewDidLoad()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
return cells.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") ?? UITableViewCell()
cell.textLabel?.text = "Test"
cell.textLabel?.text = cells[indexPath.row]
return cell
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = cells[indexPath.row]
switch cell {
case "Test":
navigationController?.pushViewController(ConversationViewController(), animated: true)
case "Settings":
navigationController?.pushViewController(SettingsViewController(), animated: true)
default:
assertionFailure("You need to impliment the action for this cell: \(cell)")
return
}
}
}
+2 -2
View File
@@ -32,10 +32,10 @@ struct MockMessage: MessageType {
var sentDate: Date
var data: MessageData
init(text: String, sender: Sender, id: String) {
init(text: String, sender: Sender, messageId: String) {
data = .text(text)
self.sender = sender
self.messageId = id
self.messageId = messageId
self.sentDate = Date()
}
@@ -0,0 +1,29 @@
import UIKit
import MessageKit
import PlaygroundSupport
//: Discover what is possible with the Avatar Class
//Get an image
let testImage = #imageLiteral(resourceName: "NiceSelfi.jpg")
var avatarView = AvatarView()
//: Uncomment any line to see how it changes the `Avatar`. Change the parameters and see the effects.
//: By default its a circlular avatar with a gray background and initals of "?"
//: Create an avatar object and set it for the view.
//var avatarObject = Avatar(image: testImage)
//avatarView.set(avatar: avatarObject)
//: If you don't have a picture for the user you can pass in there initals instead.
//avatarObject = Avatar(initals: "DL")
//avatarView.set(avatar: avatarObject)
//: Want rounded squares instead of circles just adjust the radius with the method .setCorner(radius: CGFLoat)`.
//avatarView.setCorner(radius: 5)
//: Everything has a default so if you dont want to set it then you dont have to.
//Helper method.
PlaygroundPage.current.liveView = avatarView
Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='ios'>
<playground version='5.0' target-platform='ios' display-mode='rendered'>
<timeline fileName='timeline.xctimeline'/>
</playground>
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Timeline
version = "3.0">
<TimelineItems>
</TimelineItems>
</Timeline>
+46
View File
@@ -0,0 +1,46 @@
//
// SampleData.swift
// ChatExample
//
// Created by Dan Leonard on 8/7/17.
// Copyright © 2017 MessageKit. All rights reserved.
//
import MessageKit
struct SampleData {
let Dan = Sender(id: "123456", displayName: "Dan Leonard")
let Steven = Sender(id: "654321", displayName: "Steven")
let Jobs = Sender(id: "000001", displayName: "Steve Jobs")
let Cook = Sender(id: "656361", displayName: "Tim Cook")
func getMessages() -> [MockMessage] {
let msg1 = MockMessage(text: "Check out this awesome UI library for Chat", sender: Dan, messageId: UUID().uuidString)
let msg2 = MockMessage(text: "This is insane.", sender: Steven, messageId: UUID().uuidString)
let msg3 = MockMessage(text: "Companies that get confused, that think their goal is revenue or stock price or something. You have to focus on the things that lead to those.", sender: Cook, messageId: UUID().uuidString)
let msg4 = MockMessage(text: "My favorite things in life dont cost any money. Its really clear that the most precious resource we all have is time.", sender: Jobs, messageId: UUID().uuidString)
let msg5 = MockMessage(text: "You know, this iPhone, as a matter of fact, the engine in here is made in America. And not only are the engines in here made in America, but engines are made in America and are exported. The glass on this phone is made in Kentucky. And so we've been working for years on doing more and more in the United States.", sender: Cook, messageId: UUID().uuidString)
let msg6 = MockMessage(text: "I think if you do something and it turns out pretty good, then you should go do something else wonderful, not dwell on it for too long. Just figure out whats next.", sender: Jobs, messageId: UUID().uuidString)
return [msg1, msg2, msg3, msg4, msg5, msg6]
}
func getCurrentSender() -> Sender {
return Dan
}
func getAvatarFor(sender: Sender) -> Avatar {
switch sender {
case Dan:
return Avatar(image: #imageLiteral(resourceName: "Dan-Leonard"), initals: "DL")
case Steven:
return Avatar(initals: "S")
case Jobs:
return Avatar(image: #imageLiteral(resourceName: "Steve-Jobs"), initals: "SJ")
case Cook:
return Avatar(image: #imageLiteral(resourceName: "Tim-Cook"))
default:
return Avatar()
}
}
}
+5 -3
View File
@@ -10,6 +10,7 @@
171D5AB91F36712B0053DF69 /* InputTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 171D5AB81F36712B0053DF69 /* InputTextView.swift */; };
372F6AEB1F36C15600B57FBD /* AvatarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372F6AEA1F36C15600B57FBD /* AvatarView.swift */; };
372F6AEF1F36C61000B57FBD /* AvatarViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372F6AEE1F36C61000B57FBD /* AvatarViewTests.swift */; };
37C936981F38F6AC00853DF2 /* Avatar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 37C936971F38F6AC00853DF2 /* Avatar.swift */; };
882D75841DE507320033F95F /* MessagesDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 882D75831DE507320033F95F /* MessagesDataSource.swift */; };
888CEBFC1D3FD525005178DE /* MessagesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 888CEBFB1D3FD525005178DE /* MessagesViewController.swift */; };
88916B2D1CF0DF2F00469F91 /* MessageKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 88916B221CF0DF2F00469F91 /* MessageKit.framework */; };
@@ -47,8 +48,8 @@
/* Begin PBXFileReference section */
171D5AB81F36712B0053DF69 /* InputTextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputTextView.swift; sourceTree = "<group>"; };
372F6AEA1F36C15600B57FBD /* AvatarView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AvatarView.swift; sourceTree = "<group>"; };
372F6AED1F36C1C100B57FBD /* AvatarView.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = AvatarView.playground; sourceTree = "<group>"; };
372F6AEE1F36C61000B57FBD /* AvatarViewTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AvatarViewTests.swift; sourceTree = "<group>"; };
37C936971F38F6AC00853DF2 /* Avatar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Avatar.swift; sourceTree = "<group>"; };
882D75831DE507320033F95F /* MessagesDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessagesDataSource.swift; sourceTree = "<group>"; };
888CEBFB1D3FD525005178DE /* MessagesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessagesViewController.swift; sourceTree = "<group>"; };
88916B221CF0DF2F00469F91 /* MessageKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MessageKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -151,6 +152,7 @@
children = (
B0655A291F23D77200542A83 /* Sender.swift */,
B0655A2B1F23D81600542A83 /* MessageData.swift */,
37C936971F38F6AC00853DF2 /* Avatar.swift */,
B0655A271F23D71400542A83 /* MessageDirection.swift */,
);
name = Models;
@@ -162,7 +164,6 @@
B0655A2D1F23D8BC00542A83 /* MessagesCollectionView.swift */,
B0655A4C1F244C0600542A83 /* MessageCollectionViewCell.swift */,
372F6AEA1F36C15600B57FBD /* AvatarView.swift */,
372F6AED1F36C1C100B57FBD /* AvatarView.playground */,
B0655A371F23EE8B00542A83 /* MessageInputBar.swift */,
171D5AB81F36712B0053DF69 /* InputTextView.swift */,
B074EE921F35587100ABB8C8 /* MessageHeaderView.swift */,
@@ -269,7 +270,7 @@
attributes = {
LastSwiftUpdateCheck = 0730;
LastUpgradeCheck = 0810;
ORGANIZATIONNAME = "Hexed Bits";
ORGANIZATIONNAME = MessageKit;
TargetAttributes = {
88916B211CF0DF2F00469F91 = {
CreatedOnToolsVersion = 7.3.1;
@@ -355,6 +356,7 @@
372F6AEB1F36C15600B57FBD /* AvatarView.swift in Sources */,
88916B471CF0DFE600469F91 /* MessageType.swift in Sources */,
B03FF9AF1F31BB1200754FE5 /* MessageCellDelegate.swift in Sources */,
37C936981F38F6AC00853DF2 /* Avatar.swift in Sources */,
B096438E1F2890FB004D0129 /* MessagesDisplayDataSource.swift in Sources */,
B015E8191F24623D007EDFB6 /* MessagesCollectionViewLayoutAttributes.swift in Sources */,
);
+20
View File
@@ -0,0 +1,20 @@
//
// Avatar.swift
// MessageKit
//
// Created by Dan Leonard on 8/7/17.
// Copyright © 2017 MessageKit. All rights reserved.
//
import Foundation
public struct Avatar {
public let image: UIImage?
public var initals: String = "?"
public init(image: UIImage? = nil, initals: String = "?") {
self.image = image
self.initals = initals
}
}
@@ -1,37 +0,0 @@
import UIKit
import MessageKit
import PlaygroundSupport
//: Discover what is possible with the Avatar Class
//Get an image
let testImage = #imageLiteral(resourceName: "NiceSelfi.jpg")
let view = UIView(frame: CGRect(x: 0, y: 0, width: 50, height: 200))
view.backgroundColor = UIColor.white
//: Uncomment any line to see how it changes the `Avatar`.
//: By default its a circlular avatar with a gray background and initals of ?
let avatar = AvatarView()
//: Configure any one of the initilization parameters and delete the ones you dont want to set.
//let avatar = AvatarView(size: 50, image: testImage, highlightedImage: testImage, initals: "PL", cornerRounding: 9)
//: Throw in just an image.
//let avatar = AvatarView(image: testImage)
//: Dont have an image just add the users initals
//let avatar = AvatarView(initals: "PL")
//: Want rounded squares instead of circles just change the `cornderRounding`.
//let avatar = AvatarView(image: testImage, cornerRounding: 9)
//:Change its size
//let avatar = AvatarView(size: 5)
//let avatar = AvatarView(size: 100)
//: Everything has a default so if you dont want to set it then you dont have to.
//Helper method.
PlaygroundPage.current.liveView = avatar
+32 -42
View File
@@ -26,9 +26,8 @@ import Foundation
open class AvatarView: UIView {
// MARK: - Properties
internal var initalsLabel = UILabel()
internal var avatar: Avatar = Avatar()
internal var imageView = UIImageView()
internal var initals: String = "?"
// MARK: - initializers
override init(frame: CGRect) {
@@ -36,25 +35,31 @@ open class AvatarView: UIView {
prepareView()
}
convenience public init(size: CGFloat = 30, image: UIImage? = nil, highlightedImage: UIImage? = nil, initals inInitals: String = "?", cornerRounding: CGFloat? = nil) {
let frame = CGRect(x: 0, y: 0, width: size, height: size)
self.init(frame: frame)
setCorner(radius: cornerRounding)
setBackground(color: UIColor.gray)
imageView.image = image
imageView.highlightedImage = highlightedImage
initals = inInitals
prepareView()
}
convenience public init() {
let frame = CGRect(x: 0, y: 0, width: 30, height: 30)
self.init(frame: frame)
setBackground(color: UIColor.gray)
setCorner(radius: nil)
prepareView()
}
func getImageFrom(initals: String, withColor color: UIColor = UIColor.white, fontSize: CGFloat = 14) -> UIImage {
_ = UIGraphicsBeginImageContext(CGSize(width: 30, height: 30))
let context = UIGraphicsGetCurrentContext()!
//// Text Drawing
let textRect = CGRect(x: 5, y: 6, width: 20, height: 20)
let textStyle = NSMutableParagraphStyle()
textStyle.alignment = .center
let textFontAttributes = [NSFontAttributeName: UIFont.systemFont(ofSize: fontSize), NSForegroundColorAttributeName: color, NSParagraphStyleAttributeName: textStyle]
let textTextHeight: CGFloat = initals.boundingRect(with: CGSize(width: textRect.width, height: CGFloat.infinity), options: .usesLineFragmentOrigin, attributes: textFontAttributes, context: nil).height
context.saveGState()
context.clip(to: textRect)
initals.draw(in: CGRect(x: textRect.minX, y: textRect.minY + (textRect.height - textTextHeight) / 2, width: textRect.width, height: textTextHeight), withAttributes: textFontAttributes)
context.restoreGState()
guard let renderedImage = UIGraphicsGetImageFromCurrentImageContext() else { assertionFailure("Could not create image from context"); return UIImage()}
return renderedImage
}
required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@@ -62,48 +67,27 @@ open class AvatarView: UIView {
// MARK: - internal methods
internal func prepareView() {
prepareInitalsLabel()
prepareImageView()
imageView.isHidden = imageView.image == nil
}
internal func prepareInitalsLabel() {
initalsLabel.text = initals
initalsLabel.textAlignment = .center
setInitalsFont()
addSubview(initalsLabel)
initalsLabel.center = center
initalsLabel.frame = frame
}
internal func prepareImageView() {
setBackground(color: UIColor.gray)
contentMode = .scaleAspectFill
layer.masksToBounds = true
clipsToBounds = true
addSubview(imageView)
imageView.contentMode = .scaleAspectFill
imageView.frame = frame
imageView.image = avatar.image ?? getImageFrom(initals: avatar.initals)
setCorner(radius: nil)
}
// MARK: - Open methods
// MARK: - Open setters
open func set(image: UIImage) {
imageView.image = image
}
open func setInitalsFont(size: CGFloat = 16, color: UIColor = .white) {
initalsLabel.font = UIFont.systemFont(ofSize: size)
initalsLabel.textColor = color
open func set(avatar: Avatar) {
imageView.image = avatar.image ?? getImageFrom(initals: avatar.initals)
}
open func setBackground(color: UIColor) {
backgroundColor = color
}
open func getImage() -> UIImage? {
return imageView.image
}
open func setCorner(radius: CGFloat?) {
guard let radius = radius else {
//if corner radius not set default to Circle
@@ -112,4 +96,10 @@ open class AvatarView: UIView {
}
layer.cornerRadius = radius
}
// MARK: - Open getters
open func getImage() -> UIImage? {
return imageView.image
}
}
+1 -11
View File
@@ -29,25 +29,15 @@ open class MessageCollectionViewCell: UICollectionViewCell {
// MARK: - Properties
open let messageContainerView: UIView = {
let messageContainerView = UIView()
messageContainerView.layer.cornerRadius = 12.0
messageContainerView.layer.masksToBounds = true
return messageContainerView
}()
open let avatarImageView: UIImageView = {
let avatarImageView = UIImageView()
avatarImageView.contentMode = .scaleAspectFill
avatarImageView.backgroundColor = .lightGray
avatarImageView.layer.masksToBounds = true
avatarImageView.clipsToBounds = true
return avatarImageView
}()
open var avatarImageView: AvatarView = AvatarView()
open let messageLabel: UILabel = {
let messageLabel = UILabel()
messageLabel.numberOfLines = 0
messageLabel.backgroundColor = .clear
+1 -1
View File
@@ -28,7 +28,7 @@ public protocol MessagesDisplayDataSource: class, MessagesDataSource {
func messageColorFor(_ message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> UIColor
func avatarForMessage(_ message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> AvatarView
func avatarForMessage(_ message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> Avatar
func headerForMessage(_ message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> MessageHeaderView?
+2 -3
View File
@@ -25,7 +25,7 @@ SOFTWARE.
import UIKit
open class MessagesViewController: UIViewController {
// MARK: - Properties
open var messagesCollectionView = MessagesCollectionView(frame: .zero, collectionViewLayout: MessagesCollectionViewFlowLayout())
@@ -172,8 +172,7 @@ extension MessagesViewController: UICollectionViewDataSource {
let message = displayDataSource.messageForItem(at: indexPath, in: messagesCollectionView)
let messageColor = displayDataSource.messageColorFor(message, at: indexPath, in: messagesCollectionView)
let avatar = displayDataSource.avatarForMessage(message, at: indexPath, in: messagesCollectionView)
//TODO: replace this completely
cell.avatarImageView.image = avatar.getImage()
cell.avatarImageView.set(avatar: avatar)
cell.messageContainerView.backgroundColor = messageColor
cell.configure(with: message)
+30 -40
View File
@@ -20,61 +20,51 @@ class AvatarViewTests: XCTestCase {
}
func testNoParams() {
let avatar = AvatarView()
XCTAssertEqual(avatar.initals, "?")
XCTAssertEqual(avatar.initalsLabel.text, "?")
XCTAssertEqual(avatar.layer.cornerRadius, 15.0)
XCTAssertNil(avatar.imageView.image)
XCTAssertTrue(avatar.imageView.isHidden)
XCTAssertEqual(avatar.initalsLabel.textColor, UIColor.white)
let avatarView = AvatarView()
XCTAssertEqual(avatarView.avatar.initals, "?")
XCTAssertEqual(avatarView.layer.cornerRadius, 15.0)
XCTAssertEqual(avatarView.backgroundColor, UIColor.gray)
}
func testWithImage() {
let avatar = AvatarView(image: UIImage())
let avatarView = AvatarView()
let avatar = Avatar(image: UIImage())
avatarView.set(avatar: avatar)
XCTAssertEqual(avatar.initals, "?")
XCTAssertEqual(avatar.initalsLabel.text, "?")
XCTAssertEqual(avatar.layer.cornerRadius, 15.0)
XCTAssertFalse(avatar.imageView.isHidden)
XCTAssertEqual(avatar.initalsLabel.textColor, UIColor.white)
XCTAssertEqual(avatar.backgroundColor, UIColor.gray)
XCTAssertEqual(avatarView.layer.cornerRadius, 15.0)
XCTAssertEqual(avatarView.backgroundColor, UIColor.gray)
}
func testCustom() {
let avatar = AvatarView(size: 50, image: UIImage(), highlightedImage: nil, initals: "lol", cornerRounding: 6)
XCTAssertEqual(avatar.initals, "lol")
XCTAssertEqual(avatar.initalsLabel.text, "lol")
XCTAssertEqual(avatar.layer.cornerRadius, 6.0)
XCTAssertFalse(avatar.imageView.isHidden)
XCTAssertEqual(avatar.initalsLabel.textColor, UIColor.white)
XCTAssertEqual(avatar.backgroundColor, UIColor.gray)
func testInitalsOnly() {
let avatarView = AvatarView()
let avatar = Avatar(initals: "DL")
avatarView.set(avatar: avatar)
XCTAssertEqual(avatar.initals, "DL")
XCTAssertEqual(avatarView.layer.cornerRadius, 15.0)
XCTAssertEqual(avatarView.backgroundColor, UIColor.gray)
}
func testSetBackground() {
let avatar = AvatarView(image: UIImage())
XCTAssertEqual(avatar.backgroundColor, UIColor.gray)
avatar.setBackground(color: UIColor.red)
XCTAssertEqual(avatar.backgroundColor, UIColor.red)
let avatarView = AvatarView()
XCTAssertEqual(avatarView.backgroundColor, UIColor.gray)
avatarView.setBackground(color: UIColor.red)
XCTAssertEqual(avatarView.backgroundColor, UIColor.red)
}
func testGetImage() {
let image = UIImage()
let avatar = AvatarView(image: image)
XCTAssertEqual(avatar.getImage(), image)
let avatar = Avatar(image: image)
let avatarView = AvatarView()
avatarView.set(avatar: avatar)
XCTAssertEqual(avatarView.getImage(), image)
}
func testRoundedCorners() {
let avatar = AvatarView(image: UIImage())
XCTAssertEqual(avatar.layer.cornerRadius, 15.0)
avatar.setCorner(radius: 2)
XCTAssertEqual(avatar.layer.cornerRadius, 2.0)
}
func testInitalsFont() {
let avatar = AvatarView(image: UIImage())
XCTAssertEqual(avatar.initalsLabel.textColor, UIColor.white)
XCTAssertEqual(avatar.initalsLabel.font.pointSize, 16)
avatar.setInitalsFont(size: 20, color: UIColor.blue)
XCTAssertEqual(avatar.initalsLabel.textColor, UIColor.blue)
XCTAssertEqual(avatar.initalsLabel.font.pointSize, 20)
let avatarView = AvatarView()
let avatar = Avatar(image: UIImage())
avatarView.set(avatar: avatar)
XCTAssertEqual(avatarView.layer.cornerRadius, 15.0)
avatarView.setCorner(radius: 2)
XCTAssertEqual(avatarView.layer.cornerRadius, 2.0)
}
}