Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
M
Material
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Dmitriy Stepanets
Material
Commits
15d33bde
Commit
15d33bde
authored
Sep 15, 2017
by
Daniel Dahan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
updated NavigationController and NavigationBar to utilize the Toolbar and remove duplicate code
parent
68e44743
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
96 additions
and
307 deletions
+96
-307
Sources/iOS/Bar.swift
+2
-6
Sources/iOS/NavigationBar.swift
+47
-183
Sources/iOS/NavigationController.swift
+12
-8
Sources/iOS/NavigationItem.swift
+34
-110
Sources/iOS/Toolbar.swift
+1
-0
No files found.
Sources/iOS/Bar.swift
View file @
15d33bde
...
...
@@ -108,7 +108,7 @@ open class Bar: View {
open
let
contentView
=
UIView
()
/// Left side UIViews.
open
var
leftViews
:
[
UIView
]
{
open
var
leftViews
=
[
UIView
]()
{
didSet
{
for
v
in
oldValue
{
v
.
removeFromSuperview
()
...
...
@@ -118,7 +118,7 @@ open class Bar: View {
}
/// Right side UIViews.
open
var
rightViews
:
[
UIView
]
{
open
var
rightViews
=
[
UIView
]()
{
didSet
{
for
v
in
oldValue
{
v
.
removeFromSuperview
()
...
...
@@ -142,8 +142,6 @@ open class Bar: View {
- Parameter aDecoder: A NSCoder instance.
*/
public
required
init
?(
coder
aDecoder
:
NSCoder
)
{
leftViews
=
[]
rightViews
=
[]
super
.
init
(
coder
:
aDecoder
)
}
...
...
@@ -154,8 +152,6 @@ open class Bar: View {
- Parameter frame: A CGRect instance.
*/
public
override
init
(
frame
:
CGRect
)
{
leftViews
=
[]
rightViews
=
[]
super
.
init
(
frame
:
frame
)
}
...
...
Sources/iOS/NavigationBar.swift
View file @
15d33bde
...
...
@@ -39,45 +39,36 @@ open class NavigationBar: UINavigationBar {
open
override
var
intrinsicContentSize
:
CGSize
{
return
CGSize
(
width
:
bounds
.
width
,
height
:
bounds
.
height
)
}
/// A preset wrapper around contentEdgeInsets.
open
var
contentEdgeInsetsPreset
=
EdgeInsetsPreset
.
none
{
didSet
{
/// A preset wrapper around contentEdgeInsets.
open
var
contentEdgeInsetsPreset
=
EdgeInsetsPreset
.
none
{
didSet
{
contentEdgeInsets
=
EdgeInsetsPresetToValue
(
preset
:
contentEdgeInsetsPreset
)
}
}
/// A reference to EdgeInsets.
@IBInspectable
}
}
/// A reference to EdgeInsets.
@IBInspectable
open
var
contentEdgeInsets
=
EdgeInsets
.
zero
{
didSet
{
layoutSubviews
()
}
}
/// A preset wrapper around interimSpace.
open
var
interimSpacePreset
=
InterimSpacePreset
.
none
{
didSet
{
didSet
{
layoutSubviews
()
}
}
/// A preset wrapper around interimSpace.
open
var
interimSpacePreset
=
InterimSpacePreset
.
interimSpace3
{
didSet
{
interimSpace
=
InterimSpacePresetToValue
(
preset
:
interimSpacePreset
)
}
}
/// A wrapper around grid.interimSpace.
@IBInspectable
}
}
/// A wrapper around grid.interimSpace.
@IBInspectable
open
var
interimSpace
:
InterimSpace
=
0
{
didSet
{
layoutSubviews
()
}
}
/// Grid cell factor.
@IBInspectable
open
var
gridFactor
:
CGFloat
=
12
{
didSet
{
assert
(
0
<
gridFactor
,
"[Material Error: gridFactor must be greater than 0.]"
)
layoutSubviews
()
}
}
didSet
{
layoutSubviews
()
}
}
/**
The back button image writes to the backIndicatorImage property and
...
...
@@ -151,136 +142,6 @@ open class NavigationBar: UINavigationBar {
layoutDivider
()
}
open
override
func
pushItem
(
_
item
:
UINavigationItem
,
animated
:
Bool
)
{
super
.
pushItem
(
item
,
animated
:
animated
)
layoutNavigationItem
(
item
:
item
)
}
/**
Lays out the UINavigationItem.
- Parameter item: A UINavigationItem to layout.
*/
internal
func
layoutNavigationItem
(
item
:
UINavigationItem
)
{
guard
willLayout
else
{
return
}
prepareItem
(
item
:
item
)
prepareTitleView
(
item
:
item
)
item
.
titleView
!.
frame
.
origin
=
.
zero
item
.
titleView
!.
frame
.
size
=
intrinsicContentSize
var
lc
=
0
var
rc
=
0
item
.
titleView
!.
grid
.
begin
()
item
.
titleView
!.
grid
.
views
.
removeAll
()
for
v
in
item
.
leftViews
{
if
let
b
=
v
as?
UIButton
{
b
.
contentEdgeInsets
=
.
zero
b
.
titleEdgeInsets
=
.
zero
}
v
.
frame
.
size
.
width
=
v
.
intrinsicContentSize
.
width
v
.
sizeToFit
()
v
.
grid
.
columns
=
Int
(
ceil
(
v
.
bounds
.
width
/
gridFactor
))
+
2
lc
+=
v
.
grid
.
columns
item
.
titleView
!.
grid
.
views
.
append
(
v
)
}
item
.
titleView
!.
grid
.
views
.
append
(
item
.
contentView
)
for
v
in
item
.
rightViews
{
if
let
b
=
v
as?
UIButton
{
b
.
contentEdgeInsets
=
.
zero
b
.
titleEdgeInsets
=
.
zero
}
v
.
frame
.
size
.
width
=
v
.
intrinsicContentSize
.
width
v
.
sizeToFit
()
v
.
grid
.
columns
=
Int
(
ceil
(
v
.
bounds
.
width
/
gridFactor
))
+
2
rc
+=
v
.
grid
.
columns
item
.
titleView
!.
grid
.
views
.
append
(
v
)
}
item
.
contentView
.
grid
.
begin
()
item
.
contentView
.
grid
.
offset
.
columns
=
0
var
l
:
CGFloat
=
0
var
r
:
CGFloat
=
0
if
.
center
==
item
.
contentViewAlignment
{
if
item
.
leftViews
.
count
<
item
.
rightViews
.
count
{
r
=
CGFloat
(
item
.
rightViews
.
count
)
*
interimSpace
l
=
r
}
else
{
l
=
CGFloat
(
item
.
leftViews
.
count
)
*
interimSpace
r
=
l
}
}
let
p
=
bounds
.
width
-
l
-
r
-
contentEdgeInsets
.
left
-
contentEdgeInsets
.
right
let
columns
=
Int
(
ceil
(
p
/
gridFactor
))
if
.
center
==
item
.
contentViewAlignment
{
if
lc
<
rc
{
item
.
contentView
.
grid
.
columns
=
columns
-
2
*
rc
item
.
contentView
.
grid
.
offset
.
columns
=
rc
-
lc
}
else
{
item
.
contentView
.
grid
.
columns
=
columns
-
2
*
lc
item
.
rightViews
.
first
?
.
grid
.
offset
.
columns
=
lc
-
rc
}
}
else
{
item
.
contentView
.
grid
.
columns
=
columns
-
lc
-
rc
}
item
.
titleView
!.
grid
.
axis
.
columns
=
columns
item
.
titleView
!.
grid
.
interimSpace
=
interimSpace
item
.
titleView
!.
grid
.
contentEdgeInsets
=
contentEdgeInsets
item
.
titleView
!.
grid
.
commit
()
item
.
contentView
.
grid
.
commit
()
// contentView alignment.
if
nil
!=
item
.
title
&&
""
!=
item
.
title
{
if
nil
==
item
.
titleLabel
.
superview
{
item
.
contentView
.
addSubview
(
item
.
titleLabel
)
}
item
.
titleLabel
.
frame
=
item
.
contentView
.
bounds
}
else
{
item
.
titleLabel
.
removeFromSuperview
()
}
if
0
<
item
.
detailLabel
.
text
?
.
utf16
.
count
??
0
{
if
nil
==
item
.
detailLabel
.
superview
{
item
.
contentView
.
addSubview
(
item
.
detailLabel
)
}
if
nil
==
item
.
titleLabel
.
superview
{
item
.
detailLabel
.
frame
=
item
.
contentView
.
bounds
}
else
{
item
.
titleLabel
.
sizeToFit
()
item
.
detailLabel
.
sizeToFit
()
let
diff
=
(
item
.
contentView
.
bounds
.
height
-
item
.
titleLabel
.
bounds
.
height
-
item
.
detailLabel
.
bounds
.
height
)
/
2
item
.
titleLabel
.
frame
.
size
.
height
+=
diff
item
.
titleLabel
.
frame
.
size
.
width
=
item
.
contentView
.
bounds
.
width
item
.
detailLabel
.
frame
.
size
.
height
+=
diff
item
.
detailLabel
.
frame
.
size
.
width
=
item
.
contentView
.
bounds
.
width
item
.
detailLabel
.
frame
.
origin
.
y
=
item
.
titleLabel
.
bounds
.
height
}
}
else
{
item
.
detailLabel
.
removeFromSuperview
()
}
}
/**
Prepares the view instance when intialized. When subclassing,
it is recommended to override the prepare method
...
...
@@ -292,34 +153,37 @@ open class NavigationBar: UINavigationBar {
barStyle
=
.
black
isTranslucent
=
false
depthPreset
=
.
depth1
interimSpacePreset
=
.
interimSpace3
contentEdgeInsetsPreset
=
.
square1
contentScaleFactor
=
Screen
.
scale
backButtonImage
=
Icon
.
cm
.
arrowBack
contentEdgeInsetsPreset
=
.
square1
interimSpacePreset
=
.
interimSpace3
let
image
=
UIImage
()
shadowImage
=
image
setBackgroundImage
(
image
,
for
:
.
default
)
backgroundColor
=
.
white
}
/**
Prepare the item by setting the title property to equal an empty string.
- Parameter item: A UINavigationItem to layout.
*/
private
func
prepareItem
(
item
:
UINavigationItem
)
{
item
.
hidesBackButton
=
false
item
.
setHidesBackButton
(
true
,
animated
:
false
)
}
/**
Prepare the titleView.
}
internal
extension
NavigationBar
{
/**
Lays out the UINavigationItem.
- Parameter item: A UINavigationItem to layout.
*/
private
func
prepareTitleView
(
item
:
UINavigationItem
)
{
guard
nil
==
item
.
titleView
else
{
func
layoutNavigationItem
(
item
:
UINavigationItem
)
{
guard
willLayout
else
{
return
}
item
.
titleView
=
UIView
(
frame
:
.
zero
)
}
item
.
titleView
=
item
.
toolbar
guard
let
v
=
item
.
titleView
as?
Toolbar
else
{
return
}
removeConstraints
(
constraints
)
v
.
contentEdgeInsets
=
contentEdgeInsets
v
.
interimSpace
=
interimSpace
v
.
frame
=
bounds
}
}
Sources/iOS/NavigationController.swift
View file @
15d33bde
...
...
@@ -119,18 +119,18 @@ open class NavigationController: UINavigationController {
when subclassing.
*/
open
func
prepare
()
{
isMotionEnabled
=
true
navigationBar
.
heightPreset
=
.
normal
navigationBar
.
frame
.
size
.
width
=
view
.
bounds
.
width
view
.
clipsToBounds
=
true
view
.
backgroundColor
=
.
white
view
.
contentScaleFactor
=
Screen
.
scale
// This ensures the panning gesture is available when going back between views.
if
let
v
=
interactivePopGestureRecognizer
{
v
.
isEnabled
=
true
v
.
delegate
=
self
}
if
let
v
=
interactivePopGestureRecognizer
{
v
.
isEnabled
=
true
v
.
delegate
=
self
}
}
/// Calls the layout functions for the view heirarchy.
...
...
@@ -156,20 +156,24 @@ extension NavigationController: UINavigationBarDelegate {
item
.
backButton
.
image
=
v
.
backButtonImage
}
item
.
backButton
.
addTarget
(
self
,
action
:
#selector(
handle
BackButton
)
,
for
:
.
touchUpInside
)
item
.
backButton
.
addTarget
(
self
,
action
:
#selector(
handle
(backButton:)
)
,
for
:
.
touchUpInside
)
if
!
item
.
backButton
.
isHidden
{
item
.
leftViews
.
insert
(
item
.
backButton
,
at
:
0
)
}
item
.
hidesBackButton
=
false
item
.
setHidesBackButton
(
true
,
animated
:
false
)
v
.
layoutNavigationItem
(
item
:
item
)
}
return
true
}
/// Handler for the back
button.
/// Handler for the backbutton.
@objc
internal
func
handle
BackButton
(
)
{
internal
func
handle
(
backButton
:
UIButton
)
{
popViewController
(
animated
:
true
)
}
}
...
...
Sources/iOS/NavigationItem.swift
View file @
15d33bde
...
...
@@ -35,59 +35,16 @@ fileprivate var NavigationItemKey: UInt8 = 0
fileprivate
var
NavigationItemContext
:
UInt8
=
0
fileprivate
class
NavigationItem
:
NSObject
{
/// Should center the contentView.
var
contentViewAlignment
=
ContentViewAlignment
.
center
{
didSet
{
navigationBar
?
.
layoutSubviews
()
}
}
/// A reference to the toolbar.
@objc
let
toolbar
=
Toolbar
()
/// Back Button.
lazy
var
backButton
=
IconButton
()
/// Content View.
var
contentView
=
UIView
()
/// Title label.
@objc
var
titleLabel
=
UILabel
()
/// Detail label.
var
detailLabel
=
UILabel
()
/// Left items.
var
leftViews
=
[
UIView
]()
{
didSet
{
for
v
in
oldValue
{
v
.
removeFromSuperview
()
}
navigationBar
?
.
layoutSubviews
()
}
}
/// Right items.
var
rightViews
=
[
UIView
]()
{
didSet
{
for
v
in
oldValue
{
v
.
removeFromSuperview
()
}
navigationBar
?
.
layoutSubviews
()
}
}
/// Center items.
var
centerViews
:
[
UIView
]
{
get
{
return
contentView
.
grid
.
views
}
set
(
value
)
{
contentView
.
grid
.
views
=
value
}
}
/// An optional reference to the NavigationBar.
var
navigationBar
:
NavigationBar
?
{
var
v
=
contentView
.
superview
var
v
=
toolbar
.
contentView
.
superview
while
nil
!=
v
{
if
let
navigationBar
=
v
as?
NavigationBar
{
return
navigationBar
...
...
@@ -96,76 +53,43 @@ fileprivate class NavigationItem: NSObject {
}
return
nil
}
open
override
func
observeValue
(
forKeyPath
keyPath
:
String
?,
of
object
:
Any
?,
change
:
[
NSKeyValueChangeKey
:
Any
]?,
context
:
UnsafeMutableRawPointer
?)
{
guard
"titleLabel.textAlignment"
==
keyPath
else
{
super
.
observeValue
(
forKeyPath
:
keyPath
,
of
:
object
,
change
:
change
,
context
:
context
)
return
}
fileprivate
extension
UINavigationItem
{
/// NavigationItem reference.
var
navigationItem
:
NavigationItem
{
get
{
return
AssociatedObject
.
get
(
base
:
self
,
key
:
&
NavigationItemKey
)
{
return
NavigationItem
()
}
}
set
(
value
)
{
AssociatedObject
.
set
(
base
:
self
,
key
:
&
NavigationItemKey
,
value
:
value
)
}
contentViewAlignment
=
.
center
==
titleLabel
.
textAlignment
?
.
center
:
.
full
}
deinit
{
removeObserver
(
self
,
forKeyPath
:
#keyPath(
titleLabel.textAlignment
)
)
}
/// Initializer.
override
init
()
{
super
.
init
()
prepareTitleLabel
()
prepareDetailLabel
()
}
/// Reloads the subviews for the NavigationBar.
func
reload
()
{
navigationBar
?
.
layoutSubviews
()
}
internal
extension
UINavigationItem
{
/// A reference to the NavigationItem Toolbar.
var
toolbar
:
Toolbar
{
return
navigationItem
.
toolbar
}
/// Prepares the titleLabel.
func
prepareTitleLabel
()
{
titleLabel
.
textAlignment
=
.
center
titleLabel
.
contentScaleFactor
=
Screen
.
scale
titleLabel
.
font
=
RobotoFont
.
medium
(
with
:
17
)
titleLabel
.
textColor
=
Color
.
darkText
.
primary
addObserver
(
self
,
forKeyPath
:
#keyPath(
titleLabel.textAlignment
)
,
options
:
[],
context
:
&
NavigationItemContext
)
}
/// Prepares the detailLabel.
func
prepareDetailLabel
()
{
detailLabel
.
textAlignment
=
.
center
titleLabel
.
contentScaleFactor
=
Screen
.
scale
detailLabel
.
font
=
RobotoFont
.
regular
(
with
:
12
)
detailLabel
.
textColor
=
Color
.
darkText
.
secondary
}
}
extension
UINavigationItem
{
/// NavigationItem reference.
fileprivate
var
navigationItem
:
NavigationItem
{
get
{
return
AssociatedObject
.
get
(
base
:
self
,
key
:
&
NavigationItemKey
)
{
return
NavigationItem
()
}
}
set
(
value
)
{
AssociatedObject
.
set
(
base
:
self
,
key
:
&
NavigationItemKey
,
value
:
value
)
}
}
/// Should center the contentView.
/// Should center the contentView.
open
var
contentViewAlignment
:
ContentViewAlignment
{
get
{
return
navigationItem
.
contentViewAlignment
return
toolbar
.
contentViewAlignment
}
set
(
value
)
{
navigationItem
.
contentViewAlignment
=
value
toolbar
.
contentViewAlignment
=
value
}
}
/// Content View.
open
var
contentView
:
UIView
{
return
navigationItem
.
contentView
return
toolbar
.
contentView
}
/// Back Button.
...
...
@@ -175,41 +99,41 @@ extension UINavigationItem {
/// Title Label.
open
var
titleLabel
:
UILabel
{
return
navigationItem
.
titleLabel
return
toolbar
.
titleLabel
}
/// Detail Label.
open
var
detailLabel
:
UILabel
{
return
navigationItem
.
detailLabel
return
toolbar
.
detailLabel
}
/// Left side UIViews.
open
var
leftViews
:
[
UIView
]
{
get
{
return
navigationItem
.
leftViews
return
toolbar
.
leftViews
}
set
(
value
)
{
navigationItem
.
leftViews
=
value
toolbar
.
leftViews
=
value
}
}
/// Right side UIViews.
open
var
rightViews
:
[
UIView
]
{
get
{
return
navigationItem
.
rightViews
return
toolbar
.
rightViews
}
set
(
value
)
{
navigationItem
.
rightViews
=
value
toolbar
.
rightViews
=
value
}
}
/// Center UIViews.
open
var
centerViews
:
[
UIView
]
{
get
{
return
navigationItem
.
centerViews
return
toolbar
.
centerViews
}
set
(
value
)
{
navigationItem
.
centerViews
=
value
toolbar
.
centerViews
=
value
}
}
}
Sources/iOS/Toolbar.swift
View file @
15d33bde
...
...
@@ -68,6 +68,7 @@ open class Toolbar: Bar {
super
.
observeValue
(
forKeyPath
:
keyPath
,
of
:
object
,
change
:
change
,
context
:
context
)
return
}
contentViewAlignment
=
.
center
==
titleLabel
.
textAlignment
?
.
center
:
.
full
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment