Skip to content
This repository has been archived by the owner on Aug 12, 2022. It is now read-only.

Commit

Permalink
Merge pull request #27 from readium/develop
Browse files Browse the repository at this point in the history
1.0.5
  • Loading branch information
aferditamuriqi authored Dec 9, 2018
2 parents ea6c269 + f70dfb8 commit e665d9d
Show file tree
Hide file tree
Showing 7 changed files with 263 additions and 49 deletions.
2 changes: 1 addition & 1 deletion Cartfile.resolved
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
github "Hearst-DD/ObjectMapper" "2.2.0"
github "Readium/r2-shared-swift" "07f5fe26381e0980925f7a16e8c05a1c7455ea45"
github "Readium/r2-shared-swift" "3dd222c34fcf658afd6bc4fd3e06218d773421bb"
4 changes: 4 additions & 0 deletions r2-navigator-swift.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
objects = {

/* Begin PBXBuildFile section */
1D3A2F56218C85A100108B31 /* PageTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1D3A2F55218C85A100108B31 /* PageTransition.swift */; };
F341C2711F506ED5005E6758 /* UserSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = F341C2701F506ED5005E6758 /* UserSettings.swift */; };
F3E7D3D41F4D83B000DF166D /* r2-navigator-swift.h in Headers */ = {isa = PBXBuildFile; fileRef = F3E7D3C61F4D83B000DF166D /* r2-navigator-swift.h */; settings = {ATTRIBUTES = (Public, ); }; };
F3E7D3DE1F4D845B00DF166D /* BinaryLocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3E7D3DD1F4D845B00DF166D /* BinaryLocation.swift */; };
Expand All @@ -19,6 +20,7 @@
/* End PBXBuildFile section */

/* Begin PBXFileReference section */
1D3A2F55218C85A100108B31 /* PageTransition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PageTransition.swift; sourceTree = "<group>"; };
F341C2701F506ED5005E6758 /* UserSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserSettings.swift; sourceTree = "<group>"; };
F3B2C86C1F603E79007601E4 /* SwiftyJSON.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftyJSON.framework; path = Carthage/Build/iOS/SwiftyJSON.framework; sourceTree = "<group>"; };
F3E7D3C31F4D83B000DF166D /* R2Navigator.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = R2Navigator.framework; sourceTree = BUILT_PRODUCTS_DIR; };
Expand Down Expand Up @@ -103,6 +105,7 @@
F3E7D3DD1F4D845B00DF166D /* BinaryLocation.swift */,
F3E7D3DF1F4D847E00DF166D /* Disjunction.swift */,
F341C2701F506ED5005E6758 /* UserSettings.swift */,
1D3A2F55218C85A100108B31 /* PageTransition.swift */,
);
name = EPUB;
sourceTree = "<group>";
Expand Down Expand Up @@ -203,6 +206,7 @@
F341C2711F506ED5005E6758 /* UserSettings.swift in Sources */,
F3E7D3DE1F4D845B00DF166D /* BinaryLocation.swift in Sources */,
F3E7D3E41F4D84DC00DF166D /* TriptychView.swift in Sources */,
1D3A2F56218C85A100108B31 /* PageTransition.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
117 changes: 104 additions & 13 deletions r2-navigator-swift/NavigatorViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import UIKit
import R2Shared
import WebKit
import SafariServices

public protocol NavigatorDelegate: class {
func middleTapHandler()
Expand All @@ -20,6 +21,8 @@ public protocol NavigatorDelegate: class {
/// It changes when html file resource changed
func didChangedDocumentPage(currentDocumentIndex: Int)
func didChangedPaginatedDocumentPage(currentPage: Int, documentTotalPage: Int)
func didNavigateViaInternalLinkTap(to documentIndex: Int)
func didTapExternalUrl(_ : URL)
}

public extension NavigatorDelegate {
Expand All @@ -30,6 +33,19 @@ public extension NavigatorDelegate {
func didChangedPaginatedDocumentPage(currentPage: Int, documentTotalPage: Int) {
// optional
}
func didNavigateViaInternalLinkTap(to documentIndex: Int) {
// optional
}

func didTapExternalUrl(_ url: URL) {
// optional
// TODO following lines have been moved from the original implementation and might need to be revisited at some point
let view = SFSafariViewController(url: url)

UIApplication.shared.keyWindow?.rootViewController?.present(view,
animated: true,
completion: nil)
}
}

open class NavigatorViewController: UIViewController {
Expand All @@ -41,15 +57,17 @@ open class NavigatorViewController: UIViewController {
public let publication: Publication
public weak var delegate: NavigatorDelegate?

public let pageTransition: PageTransition

/// - Parameters:
/// - publication: The publication.
/// - initialIndex: Inital index of -1 will open the publication's at the end.
public init(for publication: Publication, initialIndex: Int, initialProgression: Double?) {
public init(for publication: Publication, initialIndex: Int, initialProgression: Double?, pageTransition: PageTransition = .none) {
self.publication = publication
self.initialProgression = initialProgression
self.pageTransition = pageTransition
userSettings = UserSettings()
publication.userProperties.properties = userSettings.userProperties.properties
userSettings.userSettingsUIPreset = publication.userSettingsUIPreset
delegatee = Delegatee()
var index = initialIndex

Expand All @@ -72,6 +90,8 @@ open class NavigatorViewController: UIViewController {
open override func viewDidLoad() {
super.viewDidLoad()
delegatee.parent = self
view.backgroundColor = .clear
triptychView.backgroundColor = .clear
triptychView.delegate = delegatee
triptychView.frame = view.bounds
triptychView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
Expand All @@ -87,6 +107,7 @@ open class NavigatorViewController: UIViewController {
}

open override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Save the currently opened document index and progression.
if navigationController == nil {
let progression = triptychView.getCurrentDocumentProgression()
Expand All @@ -106,37 +127,52 @@ extension NavigatorViewController {
guard publication.spine.indices.contains(index) else {
return
}
triptychView.moveTo(index: index)
performTriptychViewTransition {
self.triptychView.moveTo(index: index)
}
}

/// Display the spine item at `index` with scroll `progression`
///
/// - Parameter index: The index of the spine item to display.
public func displaySpineItem(at index: Int, progression: Double) {
displaySpineItem(at: index)
if let webView = triptychView.currentView as? WebView {
webView.scrollAt(position: progression)
guard publication.spine.indices.contains(index) else {
return
}

performTriptychViewTransitionDelayed {
// This is so the webview will move to it's correct progression if it's not loaded into the triptych view
self.initialProgression = progression
self.triptychView.moveTo(index: index)
if let webView = self.triptychView.currentView as? WebView {
// This is needed for when the webView is loaded into the triptychView
webView.scrollAt(position: progression)
}
}
}

/// Load resource with the corresponding href.
///
/// - Parameter href: The href of the resource to load. Can contain a tag id.
public func displaySpineItem(with href: String) {
/// - Returns: The spine index for the link
public func displaySpineItem(with href: String) -> Int? {
// remove id if any
let components = href.components(separatedBy: "#")
guard let href = components.first else {
return
return nil
}
guard let index = publication.spine.index(where: { $0.href?.contains(href) ?? false }) else {
return
return nil
}
// If any id found, set the scroll position to it, else to the
// beggining of the document.
let id = (components.count > 1 ? components.last : "")

// Jumping set to true to avoid clamping.
triptychView.moveTo(index: index, id: id)
performTriptychViewTransition {
self.triptychView.moveTo(index: index, id: id)
}
return index
}

public func getSpine() -> [Link] {
Expand All @@ -160,6 +196,16 @@ extension NavigatorViewController {
}

extension NavigatorViewController: ViewDelegate {

func handleTapOnLink(with url: URL) {
delegate?.didTapExternalUrl(url)
}

func handleTapOnInternalLink(with href: String) {
guard let index = displaySpineItem(with: href) else { return }
delegate?.didNavigateViaInternalLinkTap(to: index)
}

func documentPageDidChanged(webview: WebView, currentPage: Int, totalPage: Int) {
if triptychView.currentView == webview {
delegate?.didChangedPaginatedDocumentPage(currentPage: currentPage, documentTotalPage: totalPage)
Expand All @@ -169,13 +215,13 @@ extension NavigatorViewController: ViewDelegate {
/// Display next spine item (spine item).
public func displayRightDocument() {
let delta = triptychView.direction == .rtl ? -1:1
displaySpineItem(at: triptychView.index + delta)
self.displaySpineItem(at: self.triptychView.index + delta)
}

/// Display previous document (spine item).
public func displayLeftDocument() {
let delta = triptychView.direction == .rtl ? -1:1
displaySpineItem(at: triptychView.index - delta)
self.displaySpineItem(at: self.triptychView.index - delta)
}

/// Returns the currently presented Publication's identifier.
Expand Down Expand Up @@ -206,7 +252,7 @@ extension Delegatee: TriptychViewDelegate {
public func triptychView(_ view: TriptychView, viewForIndex index: Int,
location: BinaryLocation) -> UIView {

let webView = WebView(frame: view.bounds, initialLocation: location)
let webView = WebView(frame: view.bounds, initialLocation: location, pageTransition: parent.pageTransition)
webView.direction = view.direction

let link = parent.publication.spine[index]
Expand Down Expand Up @@ -249,3 +295,48 @@ extension Delegatee: TriptychViewDelegate {
}
}


extension NavigatorViewController {

public var contentView: UIView {
return triptychView
}

func performTriptychViewTransition(commitTransition: @escaping () -> ()) {
switch pageTransition {
case .none:
commitTransition()
case .animated:
fadeTriptychView(alpha: 0) {
commitTransition()
self.fadeTriptychView(alpha: 1, completion: { })
}
}
}

/*
This is used when we want to jump to a document with proression. The rendering is sometimes very slow in this case so we have a generous delay before we show the view again.
*/
func performTriptychViewTransitionDelayed(commitTransition: @escaping () -> ()) {
switch pageTransition {
case .none:
commitTransition()
case .animated:
fadeTriptychView(alpha: 0) {
commitTransition()
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
self.fadeTriptychView(alpha: 1, completion: { })
})
}
}
}

private func fadeTriptychView(alpha: CGFloat, completion: @escaping () -> ()) {
UIView.animate(withDuration: 0.15, animations: {
self.triptychView.alpha = alpha
}) { _ in
completion()
}
}
}

17 changes: 17 additions & 0 deletions r2-navigator-swift/PageTransition.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// PageTransition.swift
// r2-navigator-swift
//
// Created by Jonas Ullström on 2018-11-02.
//
// Copyright 2018 Readium Foundation. All rights reserved.
// Use of this source code is governed by a BSD-style license which is detailed
// in the LICENSE file present in the project repository where this source code is maintained.
//

import Foundation

public enum PageTransition {
case none
case animated
}
26 changes: 21 additions & 5 deletions r2-navigator-swift/TriptychView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,6 @@ final class TriptychView: UIView {
views = Views.two(firstView: firstView, secondView: secondView)
}
default:
let currentView = viewForIndex(index, location: leading)
if index == 0 {
self.views = Views.many(
currentView: viewForIndex(index, location: leading),
Expand All @@ -266,7 +265,7 @@ final class TriptychView: UIView {
viewForIndex(index - 1, location: leading)))
} else {
views = Views.many(
currentView: currentView,
currentView: viewForIndex(index, location: leading),
otherViews: Disjunction.both(
first: viewForIndex(index - 1, location: trailing),
second: viewForIndex(index + 1, location: leading)))
Expand All @@ -280,10 +279,8 @@ final class TriptychView: UIView {
}

private func syncSubviews() {
let webViewsBefore = scrollView.subviews.compactMap { $0 as? WebView }
scrollView.subviews.forEach({
if let webview = ($0 as? WebView) {
webview.removeMessageHandlers()
}
$0.removeFromSuperview()
})

Expand All @@ -295,6 +292,10 @@ final class TriptychView: UIView {
self.scrollView.addSubview($0)
})
}

webViewsBefore.forEach {
if $0.superview == nil { $0.removeMessageHandlers() }
}
}
}

Expand Down Expand Up @@ -398,6 +399,21 @@ extension TriptychView: UIScrollViewDelegate {
}
}
}

// Set the clamping to .none in scrollViewDidEndScrollingAnimation
// and scrollViewDidEndDragging with decelerate == false,
// to prevent the bug introduced by the workaround in
// scrollViewDidEndDecelerating where the scrollview contentOffset
// is animated. When animating the contentOffset, scrollViewDidScroll
// is called without calling scrollViewDidEndDecelerating afterwards.
func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) {
clamping = .none
}

func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
if decelerate { return }
clamping = .none
}

public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {

Expand Down
1 change: 0 additions & 1 deletion r2-navigator-swift/UserSettings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ public class UserSettings {
private var pageMargins: Float = 1
private var lineHeight: Float = 1

public var userSettingsUIPreset: [ReadiumCSSName: Bool]?
public let userProperties = UserProperties()

private let userDefaults = UserDefaults.standard
Expand Down
Loading

0 comments on commit e665d9d

Please sign in to comment.