Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# OS X
.DS_Store

# Xcode
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata
*.xccheckout
profile
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserdata
*.xcuserstate

# CocoaPods
Pods
.idea

/Docs/
report.xml
663 changes: 663 additions & 0 deletions CatchTestSam/CatchTestSam.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
10 changes: 10 additions & 0 deletions CatchTestSam/CatchTestSam.xcworkspace/contents.xcworkspacedata

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
24 changes: 24 additions & 0 deletions CatchTestSam/CatchTestSam/Content/ContentViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// ContentViewController.swift
// CatchTestSam
//
// Created by smoriyasu on 26/07/20.
// Copyright © 2020 smoriyasu. All rights reserved.
//

import UIKit

class ContentViewController: UIViewController {

var record : Record?;

@IBOutlet var contentTextView: UITextView!

override func viewDidLoad() {
super.viewDidLoad()

// Do any additional setup after loading the view.
contentTextView.text = record?.content;
title = record?.title;
}
}
26 changes: 26 additions & 0 deletions CatchTestSam/CatchTestSam/List/ListCell.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// ListCell.swift
// CatchTestSam
//
// Created by smoriyasu on 26/07/20.
// Copyright © 2020 smoriyasu. All rights reserved.
//

import UIKit

class ListCell: UITableViewCell
{
var record : Record?;

override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}

func configure(record : Record)
{
self.record = record;
self.textLabel?.text = record.title;
self.detailTextLabel?.text = record.subtitle;
}
}
127 changes: 127 additions & 0 deletions CatchTestSam/CatchTestSam/List/ListViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
//
// ListViewController.swift
// CatchTestSam
//
// Created by smoriyasu on 25/07/20.
// Copyright © 2020 smoriyasu. All rights reserved.
//

import UIKit
import Refreshable

class ListViewController: UITableViewController {

let recordCollection = RecordCollection(fetchURL: URL(string: "https://raw.githubusercontent.com/catchnz/ios-test/master/data/data.json")!);
let pullDownHeight : CGFloat = 111;
let animator = SpinnerAnimator();


var coverView : UIView!
var logoView : UIImageView!

override func viewDidLoad() {
super.viewDidLoad()

self.tableView.addPullToRefresh(withAnimator: animator, height: pullDownHeight, action: self.refresh)

self.coverView = UIView();
self.coverView.isUserInteractionEnabled = false;
self.coverView.backgroundColor = .black;
self.logoView = UIImageView(image: UIImage(named: "Logo"));
self.coverView.addSubview(self.logoView);

self.tableView.addSubview(self.coverView)
}

override func viewDidLayoutSubviews() {
let safeAreaBounds = CGRect(x: 0, y: 0, width: self.tableView.bounds.width, height: self.tableView.contentSize.height);
self.coverView.frame = safeAreaBounds;

let midPoint = (self.tableView.bounds.height - (self.tableView.safeAreaInsets.top + self.tableView.safeAreaInsets.bottom)) / 2;
self.logoView.center = CGPoint(x: self.coverView.center.x, y: midPoint) ;
}

func refresh()
{
self.recordCollection.fetchRecords
{
self.tableView.reloadData();
self.hideCover();
self.tableView.stopPullToRefresh();
}
}


func hideCover()
{
UIView.animate(withDuration: 0.3, animations:
{
self.coverView.alpha = 0.25;
})
{ (finished) in

}
}

// MARK: Status Bar settings

override var prefersStatusBarHidden: Bool {
get {
return false
}
}

override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}

// MARK: - Table view delegate

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 60;
}

// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return recordCollection.records.count;
}


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ListCell", for: indexPath);

if let listCell = cell as? ListCell
{
let record = recordCollection.records[indexPath.row];
listCell.configure(record: record);
}

return cell
}

// MARK: Scroll View Delegate

override func scrollViewDidScroll(_ scrollView: UIScrollView)
{
let fixedOffset = -(self.tableView.contentOffset.y + self.tableView.safeAreaInsets.top);
let maxOffset = pullDownHeight - self.tableView.safeAreaInsets.top;
animator.setColorFromDisplacement(offset: fixedOffset, maxOffset: maxOffset);
}


// MARK: - Navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

if let destination = segue.destination as? ContentViewController, let tappedCell = sender as? ListCell
{
destination.record = tappedCell.record;
}
}


}
94 changes: 94 additions & 0 deletions CatchTestSam/CatchTestSam/List/SpinnerAnimator.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
//
// SpinnerAnimator.swift
// CatchTestSam
//
// Created by smoriyasu on 26/07/20.
// Copyright © 2020 smoriyasu. All rights reserved.
//

import UIKit
import Refreshable

class SpinnerAnimator: UIView, PullToRefreshDelegate
{
var spinner : UIImageView!
var header : UIView!

let backgroundBrightness = 0.4;

override init(frame: CGRect) {
super.init(frame: frame)
autoresizingMask = .flexibleWidth
self.backgroundColor = .black;

// The space above the Refresh Control is empty, so this view is prevent the table background from being visible.
let headerFrame = CGRect(x: 0, y: -1000, width: 2000, height: 1000);
header = UIView(frame: headerFrame);
self.header.backgroundColor = UIColor(white: backgroundBrightness, alpha: 1.0);
addSubview(self.header);

self.spinner = UIImageView(image: UIImage(named: "Spinner"));
addSubview(spinner)
spinner.isHidden = true
}

public required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func layoutSubviews() {
self.spinner.center = self.center;
}

func pullToRefreshAnimationDidStart(_ view: PullToRefreshView)
{
startAnimation();
}

func pullToRefreshAnimationDidEnd(_ view: PullToRefreshView)
{
spinner.isHidden = true
}

func pullToRefresh(_ view: PullToRefreshView, stateDidChange state: PullToRefreshState)
{
}

// Change the background color based on how far down it has been pulled.
func setColorFromDisplacement(offset: CGFloat, maxOffset: CGFloat)
{
let brightness = CGFloat((max(min(offset, maxOffset), 0) / maxOffset) * backgroundBrightness);
self.backgroundColor = UIColor(white: brightness, alpha: 1.0);
}

func startAnimation()
{
self.spinner.isHidden = false;
self.spinner.alpha = 0.0;

UIView.animate(withDuration: 0.1) {
self.spinner.alpha = 1.0;
}
animateSpinner();
}
func animateSpinner()
{
UIView.animate(
withDuration: Double(0.3),
delay: Double(0.0),
options: UIView.AnimationOptions.curveLinear,
animations: {
// Rotate the spinner by PI/2 = 90 degrees
self.spinner.transform = self.spinner.transform.rotated(by: -.pi/2)

},
completion: { finished in
if(!self.spinner.isHidden)
{
// Keep animating until it is hidden.
self.animateSpinner();
}
}
)
}
}
26 changes: 26 additions & 0 deletions CatchTestSam/CatchTestSam/Records/Record.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//
// Record.swift
// CatchTestSam
//
// Created by smoriyasu on 26/07/20.
// Copyright © 2020 smoriyasu. All rights reserved.
//

import UIKit
import SwiftyJSON

class Record: NSObject
{
var id : Int = -1;
var title : String = "";
var subtitle: String = "";
var content: String = "";

init(json : JSON)
{
id = json["id"].intValue;
title = json["title"].stringValue;
subtitle = json["subtitle"].stringValue;
content = json["content"].stringValue;
}
}
Loading