├── FacebookClone
├── Assets.xcassets
│ ├── Contents.json
│ ├── .DS_Store
│ ├── like.imageset
│ │ ├── like.png
│ │ └── Contents.json
│ ├── share.imageset
│ │ ├── share.png
│ │ └── Contents.json
│ ├── comment.imageset
│ │ ├── comment.png
│ │ └── Contents.json
│ ├── zuckdog.imageset
│ │ ├── zuckdog.jpg
│ │ └── Contents.json
│ ├── gandhi_profile.imageset
│ │ ├── gandhi.png
│ │ └── Contents.json
│ ├── more_icon.imageset
│ │ ├── more_icon@2x.png
│ │ └── Contents.json
│ ├── globe_icon.imageset
│ │ ├── globe_icon@2x.png
│ │ └── Contents.json
│ ├── globe_small.imageset
│ │ ├── globe_small.png
│ │ └── Contents.json
│ ├── zuckprofile.imageset
│ │ ├── zuckprofile.jpg
│ │ └── Contents.json
│ ├── gandhi_status.imageset
│ │ ├── gandhi_status.jpg
│ │ └── Contents.json
│ ├── steve_profile.imageset
│ │ ├── steve_profile.png
│ │ └── Contents.json
│ ├── steve_status.imageset
│ │ ├── steve_status.jpg
│ │ └── Contents.json
│ ├── news_feed_icon.imageset
│ │ ├── news_feed_icon.png
│ │ └── Contents.json
│ ├── messenger_icon.imageset
│ │ ├── messenger_icon@2x.png
│ │ └── Contents.json
│ ├── requests_icon.imageset
│ │ ├── requests_icon@2x.png
│ │ └── Contents.json
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── Utility.swift
├── Extensions.swift
├── Info.plist
├── Base.lproj
│ ├── Main.storyboard
│ └── LaunchScreen.storyboard
├── all_posts.json
├── CustomTabbarController.swift
├── AppDelegate.swift
├── OtherControllers.swift
└── FeedController.swift
├── FacebookClone.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── VamshiKrishna.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
├── xcuserdata
│ └── VamshiKrishna.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── FacebookClone.xcscheme
└── project.pbxproj
└── README.md
/FacebookClone/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBClone/HEAD/FacebookClone/Assets.xcassets/.DS_Store
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/like.imageset/like.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBClone/HEAD/FacebookClone/Assets.xcassets/like.imageset/like.png
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/share.imageset/share.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBClone/HEAD/FacebookClone/Assets.xcassets/share.imageset/share.png
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/comment.imageset/comment.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBClone/HEAD/FacebookClone/Assets.xcassets/comment.imageset/comment.png
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/zuckdog.imageset/zuckdog.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBClone/HEAD/FacebookClone/Assets.xcassets/zuckdog.imageset/zuckdog.jpg
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/gandhi_profile.imageset/gandhi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBClone/HEAD/FacebookClone/Assets.xcassets/gandhi_profile.imageset/gandhi.png
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/more_icon.imageset/more_icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBClone/HEAD/FacebookClone/Assets.xcassets/more_icon.imageset/more_icon@2x.png
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/globe_icon.imageset/globe_icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBClone/HEAD/FacebookClone/Assets.xcassets/globe_icon.imageset/globe_icon@2x.png
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/globe_small.imageset/globe_small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBClone/HEAD/FacebookClone/Assets.xcassets/globe_small.imageset/globe_small.png
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/zuckprofile.imageset/zuckprofile.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBClone/HEAD/FacebookClone/Assets.xcassets/zuckprofile.imageset/zuckprofile.jpg
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/gandhi_status.imageset/gandhi_status.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBClone/HEAD/FacebookClone/Assets.xcassets/gandhi_status.imageset/gandhi_status.jpg
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/steve_profile.imageset/steve_profile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBClone/HEAD/FacebookClone/Assets.xcassets/steve_profile.imageset/steve_profile.png
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/steve_status.imageset/steve_status.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBClone/HEAD/FacebookClone/Assets.xcassets/steve_status.imageset/steve_status.jpg
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/news_feed_icon.imageset/news_feed_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBClone/HEAD/FacebookClone/Assets.xcassets/news_feed_icon.imageset/news_feed_icon.png
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/messenger_icon.imageset/messenger_icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBClone/HEAD/FacebookClone/Assets.xcassets/messenger_icon.imageset/messenger_icon@2x.png
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/requests_icon.imageset/requests_icon@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBClone/HEAD/FacebookClone/Assets.xcassets/requests_icon.imageset/requests_icon@2x.png
--------------------------------------------------------------------------------
/FacebookClone.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/FacebookClone.xcodeproj/project.xcworkspace/xcuserdata/VamshiKrishna.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VamshiIITBHU14/FBClone/HEAD/FacebookClone.xcodeproj/project.xcworkspace/xcuserdata/VamshiKrishna.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/like.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "like.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/share.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "share.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/comment.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "comment.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/zuckdog.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "zuckdog.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/gandhi_profile.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "gandhi.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/globe_small.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "globe_small.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/more_icon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "more_icon@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/zuckprofile.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "zuckprofile.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/gandhi_status.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "gandhi_status.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/globe_icon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "globe_icon@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/steve_profile.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "steve_profile.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/steve_status.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "steve_status.jpg",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/messenger_icon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "messenger_icon@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/news_feed_icon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "news_feed_icon.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/requests_icon.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "requests_icon@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # FBClone
2 | This project is a clone of FB News Feed. Converted to Swift3 syntax (Courtesy: https://www.letsbuildthatapp.com/)
3 | It covers topics like:
4 | 1) Using a UICollectionView to make a vertical scrolling component
5 | 2) Dynamic Cell content and Loading Images
6 | 3) Load images asynchronously and caching using NSCache
7 | 4) Adding a custom UITabBar to suit to that of FB
8 | 5) Animation that zooms the image into the center of the screen
9 |
10 | All of the above with no StoryBoards used. Clean, re-usable code following MVC pattern.
11 |
--------------------------------------------------------------------------------
/FacebookClone.xcodeproj/xcuserdata/VamshiKrishna.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/FacebookClone.xcodeproj/xcuserdata/VamshiKrishna.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | FacebookClone.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 9667CBAA1ED4435F00B30B8A
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/FacebookClone/Utility.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Utility.swift
3 | // FacebookClone
4 | //
5 | // Created by Vamshi Krishna on 23/05/17.
6 | // Copyright © 2017 VamshiKrishna. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | final class Utility: NSObject {
12 |
13 | private override init() { }
14 | static let shared = Utility()
15 |
16 | func CGRectMake(_ x: CGFloat, _ y: CGFloat, _ width: CGFloat, _ height: CGFloat) -> CGRect {
17 | return CGRect(x: x, y: y, width: width, height: height)
18 | }
19 |
20 | func CGSizeMake( _ width:CGFloat, _ height:CGFloat) -> CGSize{
21 | return CGSize(width: width, height: height)
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/FacebookClone/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | }
43 | ],
44 | "info" : {
45 | "version" : 1,
46 | "author" : "xcode"
47 | }
48 | }
--------------------------------------------------------------------------------
/FacebookClone/Extensions.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Extensions.swift
3 | // FacebookClone
4 | //
5 | // Created by Vamshi Krishna on 23/05/17.
6 | // Copyright © 2017 VamshiKrishna. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | extension UIColor{
13 | static func returnRGBColor(r:CGFloat, g:CGFloat, b:CGFloat, alpha:CGFloat) -> UIColor{
14 | return UIColor(red: r/255, green: g/255, blue: b/255, alpha: alpha)
15 | }
16 | }
17 |
18 | extension UIView{
19 | func addConstraintsWithFormat(format:String, views: UIView...){
20 |
21 | var viewsDictionary = [String:UIView]()
22 | for (index, view) in views.enumerated(){
23 | let key = "v\(index)"
24 | view.translatesAutoresizingMaskIntoConstraints = false
25 | viewsDictionary[key] = view
26 |
27 | }
28 | addConstraints(NSLayoutConstraint.constraints(withVisualFormat: format, options: NSLayoutFormatOptions(), metrics: nil, views: viewsDictionary))
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/FacebookClone/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | UIViewControllerBasedStatusBarAppearance
8 |
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 |
38 |
39 |
--------------------------------------------------------------------------------
/FacebookClone/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/FacebookClone/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/FacebookClone/all_posts.json:
--------------------------------------------------------------------------------
1 | {
2 | "posts": [
3 | {
4 | "name": "Mark Zuckerberg",
5 | "location": {
6 | "city": "San Francisco",
7 | "state": "CA"
8 | },
9 | "profileImageName": "zuckprofile",
10 | "statusText": "By giving people the power to share, we're making the world more transparent.",
11 | "statusImageName": "zuckdog",
12 | "numLikes": 150,
13 | "numComments": 300,
14 | "information": "some information text"
15 | },
16 | {
17 | "name": "Steve Jobs",
18 | "location": {
19 | "city": "Cupertino",
20 | "state": "CA"
21 | },
22 | "profileImageName": "steve_profile",
23 | "statusText": "Design is not just what it looks like and feels like. Design is how it works.\n\nBeing the richest man in the cemetery doesn't matter to me. Going to bed at night saying we've done something wonderful, that's what matters to me.\n\nSometimes when you innovate, you make mistakes. It is best to admit them quickly, and get on with improving your other innovations.",
24 | "statusImageName": "steve_status",
25 | "numLikes": 111,
26 | "numComments": 222
27 | },
28 | {
29 | "name": "Mahatma Gandhi",
30 | "location": {
31 | "city": "Porbandar",
32 | "state": "India"
33 | },
34 | "profileImageName": "gandhi_profile",
35 | "statusText": "Live as if you were to die tomorrow; learn as if you were to live forever.\nThe weak can never forgive. Forgiveness is the attribute of the strong.\nHappiness is when what you think, what you say, and what you do are in harmony.",
36 | "statusImageName": "gandhi_status",
37 | "numLikes": 333,
38 | "numComments": 444
39 | }
40 | ]
41 | }
42 |
--------------------------------------------------------------------------------
/FacebookClone/CustomTabbarController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CustomTabbarController.swift
3 | // FacebookClone
4 | //
5 | // Created by Vamshi Krishna on 27/05/17.
6 | // Copyright © 2017 VamshiKrishna. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | class CustomTabbarController: UITabBarController {
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 |
16 | let feedController = FeedController(collectionViewLayout: UICollectionViewFlowLayout())
17 | let navigationController = UINavigationController(rootViewController: feedController)
18 | navigationController.title = "News Feed"
19 | navigationController.tabBarItem.image = UIImage(named: "news_feed_icon")
20 |
21 | let friendRequestController = FriendRequestsController()
22 | let secondNavigationController = UINavigationController(rootViewController: friendRequestController)
23 | secondNavigationController.title = "Requests"
24 | secondNavigationController.tabBarItem.image = UIImage(named: "requests_icon")
25 |
26 | let messengerVC = UIViewController()
27 | let messengerNavigationController = UINavigationController(rootViewController: messengerVC)
28 | messengerNavigationController.title = "Messenger"
29 | messengerNavigationController.tabBarItem.image = UIImage(named: "messenger_icon")
30 |
31 | let notificationsNavController = UINavigationController(rootViewController: UIViewController())
32 | notificationsNavController.title = "Notifications"
33 | notificationsNavController.tabBarItem.image = UIImage(named: "globe_icon")
34 |
35 | let moreNavController = UINavigationController(rootViewController: UIViewController())
36 | moreNavController.title = "More"
37 | moreNavController.tabBarItem.image = UIImage(named: "more_icon")
38 |
39 | viewControllers = [navigationController ,secondNavigationController, messengerNavigationController, notificationsNavController, moreNavController]
40 | tabBar.isTranslucent = false
41 | let topBorder = CALayer()
42 | topBorder.frame = CGRect(x: 0, y: 0, width: 1000, height: 0.5)
43 | topBorder.backgroundColor = UIColor.returnRGBColor(r: 229, g: 231, b: 235, alpha: 1).cgColor
44 | tabBar.layer.addSublayer(topBorder)
45 | tabBar.clipsToBounds = true
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/FacebookClone/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // FacebookClone
4 | //
5 | // Created by Vamshi Krishna on 23/05/17.
6 | // Copyright © 2017 VamshiKrishna. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
18 |
19 | window = UIWindow(frame: UIScreen.main.bounds)
20 | window?.makeKeyAndVisible()
21 |
22 | window?.rootViewController = CustomTabbarController()
23 | application.statusBarStyle = .lightContent
24 |
25 | UITabBar.appearance().tintColor = UIColor.returnRGBColor(r: 70, g: 146, b: 250, alpha: 1)
26 | UINavigationBar.appearance().barTintColor = UIColor(red: 51/255, green: 90/255, blue: 149/255, alpha: 1)
27 | UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName: UIColor.white]
28 |
29 | return true
30 | }
31 |
32 | func applicationWillResignActive(_ application: UIApplication) {
33 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
34 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
35 | }
36 |
37 | func applicationDidEnterBackground(_ application: UIApplication) {
38 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
39 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
40 | }
41 |
42 | func applicationWillEnterForeground(_ application: UIApplication) {
43 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
44 | }
45 |
46 | func applicationDidBecomeActive(_ application: UIApplication) {
47 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
48 | }
49 |
50 | func applicationWillTerminate(_ application: UIApplication) {
51 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
52 | }
53 |
54 |
55 | }
56 |
57 |
--------------------------------------------------------------------------------
/FacebookClone.xcodeproj/xcuserdata/VamshiKrishna.xcuserdatad/xcschemes/FacebookClone.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/FacebookClone/OtherControllers.swift:
--------------------------------------------------------------------------------
1 | //
2 | // OtherControllers.swift
3 | // FacebookClone
4 | //
5 | // Created by Vamshi Krishna on 27/05/17.
6 | // Copyright © 2017 VamshiKrishna. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | class FriendRequestsController:UITableViewController{
13 |
14 | static let cellId = "cellId"
15 | static let headerId = "headerId"
16 |
17 | override func viewDidLoad() {
18 | super.viewDidLoad()
19 | navigationItem.title = "Friend Requests"
20 | tableView.separatorColor = UIColor.returnRGBColor(r: 229, g: 231, b: 235, alpha: 1)
21 | tableView.sectionHeaderHeight = 26
22 | tableView.register(FriendRequestCell.self, forCellReuseIdentifier: FriendRequestsController.cellId)
23 | tableView.register(RequestHeader.self, forHeaderFooterViewReuseIdentifier: FriendRequestsController.headerId)
24 | tableView.allowsSelection = false
25 | }
26 |
27 | override func numberOfSections(in tableView: UITableView) -> Int {
28 | return 2
29 | }
30 |
31 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
32 | return 5
33 | }
34 |
35 | override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
36 | return 60
37 | }
38 |
39 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
40 | let cell = tableView.dequeueReusableCell(withIdentifier: FriendRequestsController.cellId, for: indexPath) as! FriendRequestCell
41 | if indexPath.row % 3 == 0 {
42 | cell.nameLabel.text = "Mark Zuckerberg"
43 | cell.requestImageView.image = UIImage(named: "zuckprofile")
44 | } else if indexPath.row % 3 == 1 {
45 | cell.nameLabel.text = "Steve Jobs"
46 | cell.requestImageView.image = UIImage(named: "steve_profile")
47 | } else {
48 | cell.nameLabel.text = "Mahatma Gandhi"
49 | cell.requestImageView.image = UIImage(named: "gandhi_profile")
50 | }
51 |
52 | cell.imageView?.backgroundColor = UIColor.black
53 | return cell
54 | }
55 |
56 | override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
57 | let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: FriendRequestsController.headerId) as! RequestHeader
58 |
59 | if section == 0 {
60 | header.nameLabel.text = "FRIEND REQUESTS"
61 | } else {
62 | header.nameLabel.text = "PEOPLE YOU MAY KNOW"
63 | }
64 |
65 | return header
66 | }
67 | }
68 |
69 | class RequestHeader: UITableViewHeaderFooterView {
70 |
71 | override init(reuseIdentifier: String?) {
72 | super.init(reuseIdentifier: reuseIdentifier)
73 | setupViews()
74 | }
75 |
76 | required init?(coder aDecoder: NSCoder) {
77 | fatalError("init(coder:) has not been implemented")
78 | }
79 |
80 | let nameLabel: UILabel = {
81 | let label = UILabel()
82 | label.text = "FRIEND REQUESTS"
83 | label.font = UIFont.systemFont(ofSize: 10)
84 | label.textColor = UIColor(white: 0.4, alpha: 1)
85 | return label
86 | }()
87 |
88 | let bottomBorderView: UIView = {
89 | let view = UIView()
90 | view.backgroundColor = UIColor.returnRGBColor(r: 229, g: 231, b: 235, alpha: 1)
91 | return view
92 | }()
93 |
94 | func setupViews(){
95 | addSubview(nameLabel)
96 | addSubview(bottomBorderView)
97 | addConstraintsWithFormat(format: "H:|-8-[v0]-8-|", views: nameLabel)
98 | addConstraintsWithFormat(format: "H:|[v0]|", views: bottomBorderView)
99 | addConstraintsWithFormat(format: "V:|[v0][v1(0.5)]|", views: nameLabel,bottomBorderView)
100 | }
101 |
102 | }
103 |
104 | class FriendRequestCell:UITableViewCell{
105 | override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
106 | super.init(style: style, reuseIdentifier: reuseIdentifier)
107 | setupViews()
108 | }
109 |
110 | required init?(coder aDecoder: NSCoder) {
111 | fatalError("init(coder:) has not been implemented")
112 | }
113 |
114 | let nameLabel:UILabel = {
115 | let label = UILabel()
116 | label.font = UIFont.systemFont(ofSize: 12)
117 | return label
118 | }()
119 |
120 | let requestImageView : UIImageView = {
121 | let imageView = UIImageView()
122 | imageView.contentMode = .scaleAspectFill
123 | imageView.backgroundColor = .blue
124 | imageView.layer.masksToBounds = true
125 | return imageView
126 | }()
127 |
128 | let confirmButton:UIButton = {
129 | let button = UIButton()
130 | button.setTitle("Confirm", for: .normal)
131 | button.setTitleColor(UIColor.white, for: .normal)
132 | button.backgroundColor = UIColor.returnRGBColor(r: 87, g: 143, b: 255, alpha: 1)
133 | button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 10)
134 | button.layer.cornerRadius = 2
135 | return button
136 | }()
137 |
138 | let deleteButton:UIButton = {
139 | let button = UIButton()
140 | button.setTitle("Delete", for: .normal)
141 | button.setTitleColor(UIColor(white: 0.3, alpha: 1), for: .normal)
142 | button.layer.borderColor = UIColor(white: 0.7, alpha: 1).cgColor
143 | button.layer.borderWidth = 1
144 | button.layer.cornerRadius = 2
145 | button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 10)
146 | return button
147 | }()
148 |
149 | func setupViews(){
150 | addSubview(nameLabel)
151 | addSubview(requestImageView)
152 | addSubview(confirmButton)
153 | addSubview(deleteButton)
154 |
155 | addConstraintsWithFormat(format: "H:|-16-[v0(52)]-8-[v1]|", views: requestImageView, nameLabel)
156 | addConstraintsWithFormat(format: "V:|-4-[v0]-4-|", views: requestImageView)
157 | addConstraintsWithFormat(format: "V:|-8-[v0]-8-[v1(24)]-8-|", views: nameLabel, confirmButton)
158 | addConstraintsWithFormat(format: "H:|-76-[v0(80)]-8-[v1(80)]", views: confirmButton, deleteButton)
159 | addConstraintsWithFormat(format: "V:[v0(24)]-8-|", views: deleteButton)
160 | }
161 | }
162 |
--------------------------------------------------------------------------------
/FacebookClone/FeedController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // FeedController.swift
3 | // FacebookClone
4 | //
5 | // Created by Vamshi Krishna on 23/05/17.
6 | // Copyright © 2017 VamshiKrishna. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | private let reuseIdentifier = "Cell"
11 |
12 | class Post:SafeJsonObject{
13 | var name:String?
14 | var statusText :String?
15 | var profileImageName:String?
16 | var statusImageName: String?
17 | var numLikes: NSNumber?
18 | var numComments: NSNumber?
19 |
20 | var location:Location?
21 |
22 | override func setValue(_ value: Any?, forKey key: String) {
23 | if key == "location" {
24 | location = Location()
25 | location?.setValuesForKeys(value as! [String:AnyObject])
26 | }
27 | else{
28 | super.setValue(value, forKey: key)
29 | }
30 |
31 | }
32 | }
33 |
34 | class Location:NSObject{
35 | var city:String?
36 | var state:String?
37 | }
38 | class SafeJsonObject:NSObject{
39 | override func setValue(_ value: Any?, forKey key: String) {
40 | let selectorString = "set\(key.uppercased().characters.first!)\(String(key.characters.dropFirst())):"
41 | let selector = Selector(selectorString)
42 | if responds(to: selector) {
43 | super.setValue(value, forKey: key)
44 | }
45 | }
46 | }
47 |
48 |
49 | class FeedController: UICollectionViewController, UICollectionViewDelegateFlowLayout {
50 | var posts = [Post]()
51 |
52 | override func viewDidLoad() {
53 | super.viewDidLoad()
54 |
55 | if let path = Bundle.main.path(forResource: "all_posts", ofType: "json") {
56 | do {
57 | let data = try(Data(contentsOf: URL(fileURLWithPath: path), options: NSData.ReadingOptions.mappedIfSafe))
58 | let jsonDictionary = try(JSONSerialization.jsonObject(with: data, options: .mutableContainers)) as? [String: Any]
59 | if let postsArray = jsonDictionary?["posts"] as? [[String: AnyObject]] {
60 | self.posts = [Post]()
61 | for postDictionary in postsArray {
62 | let post = Post()
63 | post.setValuesForKeys(postDictionary)
64 | self.posts.append(post)
65 | }
66 | }
67 | } catch let err {
68 | print(err)
69 | }
70 |
71 | }
72 |
73 | navigationItem.title = "Facebook Feed"
74 | self.collectionView?.backgroundColor = UIColor(white: 0.95, alpha: 1)
75 |
76 | self.collectionView?.register(FeedCell.self, forCellWithReuseIdentifier: reuseIdentifier)
77 | self.collectionView?.alwaysBounceVertical = true
78 | }
79 |
80 | override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
81 | return posts.count
82 | }
83 |
84 | override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
85 | let feedCell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! FeedCell
86 | feedCell.post = posts[indexPath.item]
87 | feedCell.feedController = self
88 | return feedCell
89 | }
90 |
91 | func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
92 | if let statusText = posts[indexPath.item].statusText{
93 | let rect = NSString(string: statusText).boundingRect(with: Utility.shared.CGSizeMake(view.frame.width, 1000), options: NSStringDrawingOptions.usesFontLeading.union(NSStringDrawingOptions.usesLineFragmentOrigin), attributes: [NSFontAttributeName:UIFont.systemFont(ofSize: 14)], context: nil)
94 | return Utility.shared.CGSizeMake(view.frame.width, rect.height+344+24)
95 | }
96 | return Utility.shared.CGSizeMake(view.frame.width, 500)
97 | }
98 |
99 | override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
100 | super.viewWillTransition(to: size, with: coordinator)
101 | collectionView?.collectionViewLayout.invalidateLayout()
102 | }
103 |
104 | let blackBackgroundView = UIView()
105 | var statusImageView : UIImageView?
106 | let zoomImageView = UIImageView()
107 | let navBarCoverView = UIView()
108 | let tabBarCoverView = UIView()
109 |
110 | func animateImageView(statusImageView:UIImageView){
111 | self.statusImageView = statusImageView
112 | if let startingFrame = statusImageView.superview?.convert(statusImageView.frame, to: nil){
113 | statusImageView.alpha = 0;
114 |
115 | blackBackgroundView.frame = self.view.frame
116 | blackBackgroundView.backgroundColor = UIColor.black
117 | blackBackgroundView.alpha = 0
118 | view.addSubview(blackBackgroundView)
119 |
120 | navBarCoverView.frame = Utility.shared.CGRectMake(0, 0, self.view.frame.width, 64)
121 | navBarCoverView.backgroundColor = .black
122 | navBarCoverView.alpha = 0
123 |
124 | if let keyWindow = UIApplication.shared.keyWindow{
125 | keyWindow.addSubview(navBarCoverView)
126 | tabBarCoverView.frame = Utility.shared.CGRectMake(0, keyWindow.frame.height-49, self.view.frame.width, 49)
127 | tabBarCoverView.backgroundColor = .black
128 | tabBarCoverView.alpha = 0
129 | keyWindow.addSubview(tabBarCoverView)
130 | }
131 |
132 | zoomImageView.backgroundColor = UIColor.red
133 | zoomImageView.frame = startingFrame
134 | zoomImageView.isUserInteractionEnabled = true
135 | zoomImageView.image = statusImageView.image
136 | zoomImageView.contentMode = .scaleAspectFill
137 | zoomImageView.clipsToBounds = true
138 | view.addSubview(zoomImageView)
139 |
140 | zoomImageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(zoomOut)))
141 | UIView.animate(withDuration: 0.75, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 0.5, options: .curveEaseOut, animations: { () -> Void in
142 |
143 | let height = (self.view.frame.width/startingFrame.width) * startingFrame.height
144 | let y = self.view.frame.height/2 - height/2
145 | self.zoomImageView.frame = Utility.shared.CGRectMake(0, y, self.view.frame.width, height)
146 | self.blackBackgroundView.alpha = 1
147 | self.navBarCoverView.alpha = 1
148 | self.tabBarCoverView.alpha = 1
149 |
150 | }, completion: nil)
151 |
152 | }
153 | }
154 |
155 | func zoomOut(){
156 | if let startingFrame = statusImageView?.superview?.convert((statusImageView?.frame)!, to: nil){
157 | UIView.animate(withDuration: 0.75, animations: { () -> Void in
158 | self.zoomImageView.frame = startingFrame
159 | self.blackBackgroundView.alpha = 0
160 | self.navBarCoverView.alpha = 0
161 | self.tabBarCoverView.alpha = 0
162 | }, completion: { (didComplete) -> Void in
163 | self.zoomImageView.removeFromSuperview()
164 | self.blackBackgroundView.removeFromSuperview()
165 | self.navBarCoverView.removeFromSuperview()
166 | self.statusImageView?.alpha = 1
167 | self.tabBarCoverView.removeFromSuperview()
168 | })
169 | }
170 | }
171 | }
172 |
173 | class FeedCell:UICollectionViewCell{
174 |
175 | var feedController:FeedController?
176 | func animate(){
177 | feedController?.animateImageView(statusImageView: statusImageView)
178 | }
179 |
180 | var post:Post?{
181 | didSet{
182 | if let name = post?.name {
183 |
184 | let attributedText = NSMutableAttributedString(string: name, attributes: [NSFontAttributeName: UIFont.boldSystemFont(ofSize: 14)])
185 |
186 | if let city = post?.location?.city, let state = post?.location?.state {
187 | attributedText.append(NSAttributedString(string: "\n\(city), \(state) • ", attributes: [NSFontAttributeName: UIFont.systemFont(ofSize: 12), NSForegroundColorAttributeName:
188 | UIColor.returnRGBColor(r: 155, g: 161, b: 161, alpha: 1)]))
189 | let paragraphStyle = NSMutableParagraphStyle()
190 | paragraphStyle.lineSpacing = 4
191 | attributedText.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: NSMakeRange(0, attributedText.string.characters.count))
192 | let attachment = NSTextAttachment()
193 | attachment.image = UIImage(named: "globe_small")
194 | attachment.bounds = CGRect(x: 0, y: -2, width: 12, height: 12)
195 | attributedText.append(NSAttributedString(attachment: attachment))
196 | }
197 |
198 | nameLabel.attributedText = attributedText
199 |
200 | }
201 |
202 | if let statusText = post?.statusText{
203 | statusTextView.text = statusText
204 | }
205 |
206 | if let profileImageName = post?.profileImageName{
207 | profileImageView.image = UIImage(named: profileImageName)
208 | }
209 |
210 | if let statusImageName = post?.statusImageName{
211 | statusImageView.image = UIImage(named: statusImageName)
212 | }
213 | }
214 | }
215 | override init(frame: CGRect) {
216 | super.init(frame: frame)
217 | setupViews()
218 | }
219 |
220 | required init?(coder aDecoder: NSCoder) {
221 | fatalError("init(coder:) has not been implemented")
222 | }
223 |
224 | let nameLabel:UILabel = {
225 | let label = UILabel()
226 | label.numberOfLines = 2
227 | return label
228 | }()
229 |
230 | let statusImageView : UIImageView = {
231 | let imageView = UIImageView()
232 | imageView.image = UIImage(named: "zuckdog")
233 | imageView.contentMode = .scaleAspectFill
234 | imageView.layer.masksToBounds = true
235 | imageView.isUserInteractionEnabled = true
236 | return imageView
237 | }()
238 |
239 | let statusTextView : UITextView = {
240 | let textView = UITextView()
241 | textView.font = UIFont.systemFont(ofSize: 14)
242 | textView.isScrollEnabled = false
243 | textView.isEditable = false
244 | return textView
245 | }()
246 |
247 | let profileImageView:UIImageView = {
248 | let imageView = UIImageView()
249 | imageView.image = UIImage(named: "zuckprofile")
250 | imageView.contentMode = .scaleAspectFit
251 | return imageView
252 | }()
253 |
254 | let likesCommentsLabel: UILabel = {
255 | let label = UILabel()
256 | label.text = "10000 Likes 2000 Comments"
257 | label.font = UIFont.systemFont(ofSize: 12)
258 | label.textColor = UIColor.returnRGBColor(r: 155, g: 161, b: 171, alpha: 1)
259 | return label
260 | }()
261 |
262 | let dividerLineView : UIView = {
263 | let view = UIView()
264 | view.backgroundColor = UIColor.returnRGBColor(r: 226, g: 228, b: 232, alpha: 1)
265 | return view
266 | }()
267 |
268 | static func buttonForTitleAndImage(title:String, imageName:String) -> UIButton{
269 | let button = UIButton()
270 | button.setTitle(title, for: .normal)
271 | button.setTitleColor(UIColor.returnRGBColor(r: 142, g: 148, b: 161, alpha: 1), for: .normal)
272 | button.setImage(UIImage(named:imageName), for: .normal)
273 | button.titleEdgeInsets = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 0)
274 | button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 14)
275 | return button
276 | }
277 |
278 | let likeButton = FeedCell.buttonForTitleAndImage(title: "Like", imageName: "like")
279 | let commentButton = FeedCell.buttonForTitleAndImage(title: "Comment", imageName: "comment")
280 | let shareButton = FeedCell.buttonForTitleAndImage(title: "Share", imageName: "share")
281 |
282 | func setupViews(){
283 | backgroundColor = UIColor.white
284 |
285 | addSubview(nameLabel)
286 | addSubview(profileImageView)
287 | addSubview(statusTextView)
288 | addSubview(statusImageView)
289 | addSubview(likesCommentsLabel)
290 | addSubview(dividerLineView)
291 | addSubview(likeButton)
292 | addSubview(commentButton)
293 | addSubview(shareButton)
294 |
295 | statusImageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(animate)))
296 |
297 | addConstraintsWithFormat(format: "H:|-8-[v0(44)]-8-[v1]|", views: profileImageView, nameLabel)
298 | addConstraintsWithFormat(format: "H:|-4-[v0]-4-|", views: statusTextView)
299 | addConstraintsWithFormat(format: "H:|[v0]|", views: statusImageView)
300 | addConstraintsWithFormat(format: "H:|-12-[v0]|", views: likesCommentsLabel)
301 | addConstraintsWithFormat(format: "H:|-12-[v0]-12-|", views: dividerLineView)
302 | addConstraintsWithFormat(format: "H:|[v0(v2)][v1(v2)][v2]|", views: likeButton, commentButton ,shareButton)
303 | addConstraintsWithFormat(format: "V:|-12-[v0]", views: nameLabel)
304 | addConstraintsWithFormat(format: "V:|-8-[v0(44)]-4-[v1]-4-[v2(200)]-8-[v3(24)]-8-[v4(0.4)][v5(44)]|", views: profileImageView, statusTextView, statusImageView, likesCommentsLabel, dividerLineView, likeButton)
305 | addConstraintsWithFormat(format: "V:[v0(44)]|", views: commentButton)
306 | addConstraintsWithFormat(format: "V:[v0(44)]|", views: shareButton)
307 |
308 | }
309 | }
310 |
--------------------------------------------------------------------------------
/FacebookClone.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 962DDD121ED9391200741BF6 /* CustomTabbarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 962DDD111ED9391100741BF6 /* CustomTabbarController.swift */; };
11 | 962DDD141ED941AC00741BF6 /* OtherControllers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 962DDD131ED941AC00741BF6 /* OtherControllers.swift */; };
12 | 962DDD161ED969A900741BF6 /* all_posts.json in Resources */ = {isa = PBXBuildFile; fileRef = 962DDD151ED969A900741BF6 /* all_posts.json */; };
13 | 9667CBAF1ED4435F00B30B8A /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9667CBAE1ED4435F00B30B8A /* AppDelegate.swift */; };
14 | 9667CBB41ED4435F00B30B8A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9667CBB21ED4435F00B30B8A /* Main.storyboard */; };
15 | 9667CBB61ED4435F00B30B8A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9667CBB51ED4435F00B30B8A /* Assets.xcassets */; };
16 | 9667CBB91ED4435F00B30B8A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9667CBB71ED4435F00B30B8A /* LaunchScreen.storyboard */; };
17 | 9667CBC31ED4443D00B30B8A /* FeedController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9667CBC21ED4443D00B30B8A /* FeedController.swift */; };
18 | 9667CBC51ED445B100B30B8A /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9667CBC41ED445B100B30B8A /* Extensions.swift */; };
19 | 9667CBC71ED45B1500B30B8A /* Utility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9667CBC61ED45B1500B30B8A /* Utility.swift */; };
20 | /* End PBXBuildFile section */
21 |
22 | /* Begin PBXFileReference section */
23 | 962DDD111ED9391100741BF6 /* CustomTabbarController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomTabbarController.swift; sourceTree = ""; };
24 | 962DDD131ED941AC00741BF6 /* OtherControllers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OtherControllers.swift; sourceTree = ""; };
25 | 962DDD151ED969A900741BF6 /* all_posts.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = all_posts.json; sourceTree = ""; };
26 | 9667CBAB1ED4435F00B30B8A /* FacebookClone.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FacebookClone.app; sourceTree = BUILT_PRODUCTS_DIR; };
27 | 9667CBAE1ED4435F00B30B8A /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
28 | 9667CBB31ED4435F00B30B8A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
29 | 9667CBB51ED4435F00B30B8A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
30 | 9667CBB81ED4435F00B30B8A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
31 | 9667CBBA1ED4435F00B30B8A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
32 | 9667CBC21ED4443D00B30B8A /* FeedController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeedController.swift; sourceTree = ""; };
33 | 9667CBC41ED445B100B30B8A /* Extensions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; };
34 | 9667CBC61ED45B1500B30B8A /* Utility.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Utility.swift; sourceTree = ""; };
35 | /* End PBXFileReference section */
36 |
37 | /* Begin PBXFrameworksBuildPhase section */
38 | 9667CBA81ED4435F00B30B8A /* Frameworks */ = {
39 | isa = PBXFrameworksBuildPhase;
40 | buildActionMask = 2147483647;
41 | files = (
42 | );
43 | runOnlyForDeploymentPostprocessing = 0;
44 | };
45 | /* End PBXFrameworksBuildPhase section */
46 |
47 | /* Begin PBXGroup section */
48 | 9667CBA21ED4435F00B30B8A = {
49 | isa = PBXGroup;
50 | children = (
51 | 9667CBAD1ED4435F00B30B8A /* FacebookClone */,
52 | 9667CBAC1ED4435F00B30B8A /* Products */,
53 | );
54 | sourceTree = "";
55 | };
56 | 9667CBAC1ED4435F00B30B8A /* Products */ = {
57 | isa = PBXGroup;
58 | children = (
59 | 9667CBAB1ED4435F00B30B8A /* FacebookClone.app */,
60 | );
61 | name = Products;
62 | sourceTree = "";
63 | };
64 | 9667CBAD1ED4435F00B30B8A /* FacebookClone */ = {
65 | isa = PBXGroup;
66 | children = (
67 | 9667CBAE1ED4435F00B30B8A /* AppDelegate.swift */,
68 | 962DDD111ED9391100741BF6 /* CustomTabbarController.swift */,
69 | 962DDD131ED941AC00741BF6 /* OtherControllers.swift */,
70 | 9667CBC21ED4443D00B30B8A /* FeedController.swift */,
71 | 962DDD151ED969A900741BF6 /* all_posts.json */,
72 | 9667CBC41ED445B100B30B8A /* Extensions.swift */,
73 | 9667CBC61ED45B1500B30B8A /* Utility.swift */,
74 | 9667CBB21ED4435F00B30B8A /* Main.storyboard */,
75 | 9667CBB51ED4435F00B30B8A /* Assets.xcassets */,
76 | 9667CBB71ED4435F00B30B8A /* LaunchScreen.storyboard */,
77 | 9667CBBA1ED4435F00B30B8A /* Info.plist */,
78 | );
79 | path = FacebookClone;
80 | sourceTree = "";
81 | };
82 | /* End PBXGroup section */
83 |
84 | /* Begin PBXNativeTarget section */
85 | 9667CBAA1ED4435F00B30B8A /* FacebookClone */ = {
86 | isa = PBXNativeTarget;
87 | buildConfigurationList = 9667CBBD1ED4435F00B30B8A /* Build configuration list for PBXNativeTarget "FacebookClone" */;
88 | buildPhases = (
89 | 9667CBA71ED4435F00B30B8A /* Sources */,
90 | 9667CBA81ED4435F00B30B8A /* Frameworks */,
91 | 9667CBA91ED4435F00B30B8A /* Resources */,
92 | );
93 | buildRules = (
94 | );
95 | dependencies = (
96 | );
97 | name = FacebookClone;
98 | productName = FacebookClone;
99 | productReference = 9667CBAB1ED4435F00B30B8A /* FacebookClone.app */;
100 | productType = "com.apple.product-type.application";
101 | };
102 | /* End PBXNativeTarget section */
103 |
104 | /* Begin PBXProject section */
105 | 9667CBA31ED4435F00B30B8A /* Project object */ = {
106 | isa = PBXProject;
107 | attributes = {
108 | LastSwiftUpdateCheck = 0830;
109 | LastUpgradeCheck = 0830;
110 | ORGANIZATIONNAME = VamshiKrishna;
111 | TargetAttributes = {
112 | 9667CBAA1ED4435F00B30B8A = {
113 | CreatedOnToolsVersion = 8.3.2;
114 | DevelopmentTeam = BJBC582Q56;
115 | ProvisioningStyle = Automatic;
116 | };
117 | };
118 | };
119 | buildConfigurationList = 9667CBA61ED4435F00B30B8A /* Build configuration list for PBXProject "FacebookClone" */;
120 | compatibilityVersion = "Xcode 3.2";
121 | developmentRegion = English;
122 | hasScannedForEncodings = 0;
123 | knownRegions = (
124 | en,
125 | Base,
126 | );
127 | mainGroup = 9667CBA21ED4435F00B30B8A;
128 | productRefGroup = 9667CBAC1ED4435F00B30B8A /* Products */;
129 | projectDirPath = "";
130 | projectRoot = "";
131 | targets = (
132 | 9667CBAA1ED4435F00B30B8A /* FacebookClone */,
133 | );
134 | };
135 | /* End PBXProject section */
136 |
137 | /* Begin PBXResourcesBuildPhase section */
138 | 9667CBA91ED4435F00B30B8A /* Resources */ = {
139 | isa = PBXResourcesBuildPhase;
140 | buildActionMask = 2147483647;
141 | files = (
142 | 9667CBB91ED4435F00B30B8A /* LaunchScreen.storyboard in Resources */,
143 | 9667CBB61ED4435F00B30B8A /* Assets.xcassets in Resources */,
144 | 9667CBB41ED4435F00B30B8A /* Main.storyboard in Resources */,
145 | 962DDD161ED969A900741BF6 /* all_posts.json in Resources */,
146 | );
147 | runOnlyForDeploymentPostprocessing = 0;
148 | };
149 | /* End PBXResourcesBuildPhase section */
150 |
151 | /* Begin PBXSourcesBuildPhase section */
152 | 9667CBA71ED4435F00B30B8A /* Sources */ = {
153 | isa = PBXSourcesBuildPhase;
154 | buildActionMask = 2147483647;
155 | files = (
156 | 962DDD121ED9391200741BF6 /* CustomTabbarController.swift in Sources */,
157 | 9667CBC71ED45B1500B30B8A /* Utility.swift in Sources */,
158 | 962DDD141ED941AC00741BF6 /* OtherControllers.swift in Sources */,
159 | 9667CBAF1ED4435F00B30B8A /* AppDelegate.swift in Sources */,
160 | 9667CBC51ED445B100B30B8A /* Extensions.swift in Sources */,
161 | 9667CBC31ED4443D00B30B8A /* FeedController.swift in Sources */,
162 | );
163 | runOnlyForDeploymentPostprocessing = 0;
164 | };
165 | /* End PBXSourcesBuildPhase section */
166 |
167 | /* Begin PBXVariantGroup section */
168 | 9667CBB21ED4435F00B30B8A /* Main.storyboard */ = {
169 | isa = PBXVariantGroup;
170 | children = (
171 | 9667CBB31ED4435F00B30B8A /* Base */,
172 | );
173 | name = Main.storyboard;
174 | sourceTree = "";
175 | };
176 | 9667CBB71ED4435F00B30B8A /* LaunchScreen.storyboard */ = {
177 | isa = PBXVariantGroup;
178 | children = (
179 | 9667CBB81ED4435F00B30B8A /* Base */,
180 | );
181 | name = LaunchScreen.storyboard;
182 | sourceTree = "";
183 | };
184 | /* End PBXVariantGroup section */
185 |
186 | /* Begin XCBuildConfiguration section */
187 | 9667CBBB1ED4435F00B30B8A /* Debug */ = {
188 | isa = XCBuildConfiguration;
189 | buildSettings = {
190 | ALWAYS_SEARCH_USER_PATHS = NO;
191 | CLANG_ANALYZER_NONNULL = YES;
192 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
193 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
194 | CLANG_CXX_LIBRARY = "libc++";
195 | CLANG_ENABLE_MODULES = YES;
196 | CLANG_ENABLE_OBJC_ARC = YES;
197 | CLANG_WARN_BOOL_CONVERSION = YES;
198 | CLANG_WARN_CONSTANT_CONVERSION = YES;
199 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
200 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
201 | CLANG_WARN_EMPTY_BODY = YES;
202 | CLANG_WARN_ENUM_CONVERSION = YES;
203 | CLANG_WARN_INFINITE_RECURSION = YES;
204 | CLANG_WARN_INT_CONVERSION = YES;
205 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
206 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
207 | CLANG_WARN_UNREACHABLE_CODE = YES;
208 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
209 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
210 | COPY_PHASE_STRIP = NO;
211 | DEBUG_INFORMATION_FORMAT = dwarf;
212 | ENABLE_STRICT_OBJC_MSGSEND = YES;
213 | ENABLE_TESTABILITY = YES;
214 | GCC_C_LANGUAGE_STANDARD = gnu99;
215 | GCC_DYNAMIC_NO_PIC = NO;
216 | GCC_NO_COMMON_BLOCKS = YES;
217 | GCC_OPTIMIZATION_LEVEL = 0;
218 | GCC_PREPROCESSOR_DEFINITIONS = (
219 | "DEBUG=1",
220 | "$(inherited)",
221 | );
222 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
223 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
224 | GCC_WARN_UNDECLARED_SELECTOR = YES;
225 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
226 | GCC_WARN_UNUSED_FUNCTION = YES;
227 | GCC_WARN_UNUSED_VARIABLE = YES;
228 | IPHONEOS_DEPLOYMENT_TARGET = 10.3;
229 | MTL_ENABLE_DEBUG_INFO = YES;
230 | ONLY_ACTIVE_ARCH = YES;
231 | SDKROOT = iphoneos;
232 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
233 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
234 | };
235 | name = Debug;
236 | };
237 | 9667CBBC1ED4435F00B30B8A /* Release */ = {
238 | isa = XCBuildConfiguration;
239 | buildSettings = {
240 | ALWAYS_SEARCH_USER_PATHS = NO;
241 | CLANG_ANALYZER_NONNULL = YES;
242 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
243 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
244 | CLANG_CXX_LIBRARY = "libc++";
245 | CLANG_ENABLE_MODULES = YES;
246 | CLANG_ENABLE_OBJC_ARC = YES;
247 | CLANG_WARN_BOOL_CONVERSION = YES;
248 | CLANG_WARN_CONSTANT_CONVERSION = YES;
249 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
250 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
251 | CLANG_WARN_EMPTY_BODY = YES;
252 | CLANG_WARN_ENUM_CONVERSION = YES;
253 | CLANG_WARN_INFINITE_RECURSION = YES;
254 | CLANG_WARN_INT_CONVERSION = YES;
255 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
256 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
257 | CLANG_WARN_UNREACHABLE_CODE = YES;
258 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
259 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
260 | COPY_PHASE_STRIP = NO;
261 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
262 | ENABLE_NS_ASSERTIONS = NO;
263 | ENABLE_STRICT_OBJC_MSGSEND = YES;
264 | GCC_C_LANGUAGE_STANDARD = gnu99;
265 | GCC_NO_COMMON_BLOCKS = YES;
266 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
267 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
268 | GCC_WARN_UNDECLARED_SELECTOR = YES;
269 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
270 | GCC_WARN_UNUSED_FUNCTION = YES;
271 | GCC_WARN_UNUSED_VARIABLE = YES;
272 | IPHONEOS_DEPLOYMENT_TARGET = 10.3;
273 | MTL_ENABLE_DEBUG_INFO = NO;
274 | SDKROOT = iphoneos;
275 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
276 | VALIDATE_PRODUCT = YES;
277 | };
278 | name = Release;
279 | };
280 | 9667CBBE1ED4435F00B30B8A /* Debug */ = {
281 | isa = XCBuildConfiguration;
282 | buildSettings = {
283 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
284 | DEVELOPMENT_TEAM = BJBC582Q56;
285 | INFOPLIST_FILE = FacebookClone/Info.plist;
286 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
287 | PRODUCT_BUNDLE_IDENTIFIER = VamshiKrishna.FacebookClone;
288 | PRODUCT_NAME = "$(TARGET_NAME)";
289 | SWIFT_VERSION = 3.0;
290 | };
291 | name = Debug;
292 | };
293 | 9667CBBF1ED4435F00B30B8A /* Release */ = {
294 | isa = XCBuildConfiguration;
295 | buildSettings = {
296 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
297 | DEVELOPMENT_TEAM = BJBC582Q56;
298 | INFOPLIST_FILE = FacebookClone/Info.plist;
299 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
300 | PRODUCT_BUNDLE_IDENTIFIER = VamshiKrishna.FacebookClone;
301 | PRODUCT_NAME = "$(TARGET_NAME)";
302 | SWIFT_VERSION = 3.0;
303 | };
304 | name = Release;
305 | };
306 | /* End XCBuildConfiguration section */
307 |
308 | /* Begin XCConfigurationList section */
309 | 9667CBA61ED4435F00B30B8A /* Build configuration list for PBXProject "FacebookClone" */ = {
310 | isa = XCConfigurationList;
311 | buildConfigurations = (
312 | 9667CBBB1ED4435F00B30B8A /* Debug */,
313 | 9667CBBC1ED4435F00B30B8A /* Release */,
314 | );
315 | defaultConfigurationIsVisible = 0;
316 | defaultConfigurationName = Release;
317 | };
318 | 9667CBBD1ED4435F00B30B8A /* Build configuration list for PBXNativeTarget "FacebookClone" */ = {
319 | isa = XCConfigurationList;
320 | buildConfigurations = (
321 | 9667CBBE1ED4435F00B30B8A /* Debug */,
322 | 9667CBBF1ED4435F00B30B8A /* Release */,
323 | );
324 | defaultConfigurationIsVisible = 0;
325 | defaultConfigurationName = Release;
326 | };
327 | /* End XCConfigurationList section */
328 | };
329 | rootObject = 9667CBA31ED4435F00B30B8A /* Project object */;
330 | }
331 |
--------------------------------------------------------------------------------