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
037ec0ee
Commit
037ec0ee
authored
Jan 17, 2018
by
Orkhan Alikhanov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Moved hardcoded magic numbers, to the `Constants` struct
parent
e29304ce
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
67 additions
and
27 deletions
+67
-27
Sources/iOS/DialogView.swift
+67
-27
No files found.
Sources/iOS/DialogView.swift
View file @
037ec0ee
...
@@ -83,8 +83,9 @@ open class DialogView: UIView {
...
@@ -83,8 +83,9 @@ open class DialogView: UIView {
h
+=
titleAreaSizeThatFits
(
width
:
w
)
.
height
h
+=
titleAreaSizeThatFits
(
width
:
w
)
.
height
h
+=
buttonAreaSizeThatFits
(
width
:
w
)
.
height
h
+=
buttonAreaSizeThatFits
(
width
:
w
)
.
height
h
+=
contentViewSizeThatFits
(
width
:
w
)
.
height
h
+=
contentViewSizeThatFits
(
width
:
w
)
.
height
h
=
min
(
h
,
size
.
height
)
return
CGSize
(
width
:
w
,
height
:
min
(
h
,
size
.
height
)
)
return
CGSize
(
width
:
w
,
height
:
h
)
}
}
open
override
func
layoutSubviews
()
{
open
override
func
layoutSubviews
()
{
...
@@ -103,9 +104,10 @@ open class DialogView: UIView {
...
@@ -103,9 +104,10 @@ open class DialogView: UIView {
/// Override this if you are using custom view in title area
/// Override this if you are using custom view in title area
open
func
titleAreaSizeThatFits
(
width
:
CGFloat
)
->
CGSize
{
open
func
titleAreaSizeThatFits
(
width
:
CGFloat
)
->
CGSize
{
guard
!
titleLabel
.
isEmpty
else
{
return
.
zero
}
guard
!
titleLabel
.
isEmpty
else
{
return
.
zero
}
var
size
=
titleLabel
.
sizeThatFits
(
CGSize
(
width
:
width
-
24
-
24
,
height
:
.
greatestFiniteMagnitude
))
let
insets
=
Constants
.
titleArea
.
insets
size
.
width
+=
24
+
24
var
size
=
titleLabel
.
sizeThatFits
(
CGSize
(
width
:
width
-
insets
.
left
-
insets
.
right
,
height
:
.
greatestFiniteMagnitude
))
size
.
height
+=
24
+
20
size
.
width
+=
insets
.
left
+
insets
.
right
size
.
height
+=
insets
.
top
+
insets
.
bottom
return
size
return
size
}
}
...
@@ -113,28 +115,57 @@ open class DialogView: UIView {
...
@@ -113,28 +115,57 @@ open class DialogView: UIView {
guard
!
nonHiddenButtons
.
isEmpty
else
{
return
.
zero
}
guard
!
nonHiddenButtons
.
isEmpty
else
{
return
.
zero
}
let
isStacked
=
requiredButtonAreaWidth
>
width
let
isStacked
=
requiredButtonAreaWidth
>
width
let
buttonsHeight
=
Constants
.
button
.
height
*
CGFloat
(
isStacked
?
nonHiddenButtons
.
count
:
1
)
let
buttonsInterim
=
isStacked
?
CGFloat
(
nonHiddenButtons
.
count
-
1
)
*
Constants
.
button
.
interimStacked
:
0
let
insets
=
isStacked
?
Constants
.
buttonArea
.
insetsStacked
:
Constants
.
buttonArea
.
insets
let
h
=
buttonsInterim
+
buttonsHeight
+
insets
.
bottom
+
insets
.
top
let
w
=
min
(
width
,
isStacked
?
requiredButtonAreaWidthForStacked
:
requiredButtonAreaWidth
)
let
w
=
min
(
width
,
isStacked
?
requiredButtonAreaWidthForStacked
:
requiredButtonAreaWidth
)
let
h
=
isStacked
?
CGFloat
(
8
+
nonHiddenButtons
.
count
*
48
)
:
52
return
CGSize
(
width
:
w
,
height
:
h
)
return
CGSize
(
width
:
w
,
height
:
h
)
}
}
open
func
contentViewSizeThatFits
(
width
:
CGFloat
)
->
CGSize
{
open
func
contentViewSizeThatFits
(
width
:
CGFloat
)
->
CGSize
{
guard
!
detailsLabel
.
isEmpty
else
{
return
.
zero
}
guard
!
detailsLabel
.
isEmpty
else
{
return
.
zero
}
var
size
=
detailsLabel
.
sizeThatFits
(
CGSize
(
width
:
width
-
24
-
24
,
height
:
.
greatestFiniteMagnitude
))
let
insets
=
titleLabel
.
isEmpty
?
Constants
.
contentView
.
insetsNoTitle
:
Constants
.
contentView
.
insets
size
.
width
+=
24
+
24
var
size
=
detailsLabel
.
sizeThatFits
(
CGSize
(
width
:
width
-
insets
.
left
-
insets
.
right
,
height
:
.
greatestFiniteMagnitude
))
let
additional
:
CGFloat
=
titleLabel
.
isEmpty
?
20
:
0
// if no title area, will be pushed 20 points below
size
.
width
+=
insets
.
left
+
insets
.
right
size
.
height
+=
24
+
0
+
additional
size
.
height
+=
insets
.
top
+
insets
.
bottom
return
size
return
size
}
}
}
}
private
struct
Constants
{
struct
titleArea
{
static
let
insets
=
UIEdgeInsets
(
top
:
24
,
left
:
24
,
bottom
:
20
,
right
:
24
)
}
struct
contentView
{
static
let
insets
=
UIEdgeInsets
(
top
:
0
,
left
:
24
,
bottom
:
24
,
right
:
24
)
static
let
insetsNoTitle
=
UIEdgeInsets
(
top
:
20
,
left
:
24
,
bottom
:
24
,
right
:
24
)
}
struct
buttonArea
{
static
let
insets
=
UIEdgeInsets
(
top
:
8
,
left
:
8
,
bottom
:
8
,
right
:
8
)
static
let
insetsStacked
=
UIEdgeInsets
(
top
:
6
,
left
:
8
,
bottom
:
14
,
right
:
8
)
}
struct
button
{
static
let
insets
=
UIEdgeInsets
(
top
:
0
,
left
:
8
,
bottom
:
0
,
right
:
8
)
static
let
minWidth
:
CGFloat
=
64
static
let
height
:
CGFloat
=
36
static
let
interimStacked
:
CGFloat
=
12
static
let
interim
:
CGFloat
=
8
}
}
private
extension
DialogView
{
private
extension
DialogView
{
func
layoutTitleArea
()
{
func
layoutTitleArea
()
{
let
size
=
CGSize
(
width
:
frame
.
width
,
height
:
titleAreaSizeThatFits
(
width
:
frame
.
width
)
.
height
)
let
size
=
CGSize
(
width
:
frame
.
width
,
height
:
titleAreaSizeThatFits
(
width
:
frame
.
width
)
.
height
)
titleArea
.
frame
.
size
=
size
titleArea
.
frame
.
size
=
size
guard
!
titleLabel
.
isEmpty
else
{
return
}
guard
!
titleLabel
.
isEmpty
else
{
return
}
titleLabel
.
frame
=
CGRect
(
x
:
24
,
y
:
24
,
width
:
size
.
width
-
24
-
24
,
height
:
size
.
height
-
24
-
20
)
let
rect
=
CGRect
(
origin
:
.
zero
,
size
:
size
)
titleLabel
.
frame
=
UIEdgeInsetsInsetRect
(
rect
,
Constants
.
titleArea
.
insets
)
}
}
func
layoutButtonArea
()
{
func
layoutButtonArea
()
{
...
@@ -147,25 +178,29 @@ private extension DialogView {
...
@@ -147,25 +178,29 @@ private extension DialogView {
let
isStacked
=
requiredButtonAreaWidth
>
width
let
isStacked
=
requiredButtonAreaWidth
>
width
if
isStacked
{
if
isStacked
{
let
insets
=
Constants
.
buttonArea
.
insetsStacked
buttons
.
forEach
{
buttons
.
forEach
{
let
w
=
min
(
$0
.
optimalWidth
,
width
-
8
-
8
)
let
w
=
min
(
$0
.
optimalWidth
,
width
-
insets
.
left
-
insets
.
right
)
$0
.
frame
.
size
=
CGSize
(
width
:
w
,
height
:
36
)
$0
.
frame
.
size
=
CGSize
(
width
:
w
,
height
:
Constants
.
button
.
height
)
$0
.
frame
.
origin
.
x
=
width
-
8
-
w
$0
.
frame
.
origin
.
x
=
width
-
insets
.
right
-
w
}
}
positiveButton
.
frame
.
origin
.
y
=
6
positiveButton
.
frame
.
origin
.
y
=
insets
.
top
let
belowPositive
=
positiveButton
.
isHidden
?
6
:
positiveButton
.
frame
.
maxY
+
6
+
6
let
belowPositive
=
positiveButton
.
isHidden
?
insets
.
top
:
positiveButton
.
frame
.
maxY
+
Constants
.
button
.
interimStacked
negativeButton
.
frame
.
origin
.
y
=
belowPositive
negativeButton
.
frame
.
origin
.
y
=
belowPositive
neutralButton
.
frame
.
origin
.
y
=
negativeButton
.
isHidden
?
belowPositive
:
(
negativeButton
.
frame
.
maxY
+
6
+
6
)
neutralButton
.
frame
.
origin
.
y
=
negativeButton
.
isHidden
?
belowPositive
:
negativeButton
.
frame
.
maxY
+
Constants
.
button
.
interimStacked
}
else
{
}
else
{
let
insets
=
Constants
.
buttonArea
.
insets
buttons
.
forEach
{
buttons
.
forEach
{
$0
.
frame
.
size
=
CGSize
(
width
:
$0
.
optimalWidth
,
height
:
36
)
$0
.
frame
.
size
=
CGSize
(
width
:
$0
.
optimalWidth
,
height
:
Constants
.
button
.
height
)
$0
.
frame
.
origin
.
y
=
8
$0
.
frame
.
origin
.
y
=
insets
.
top
}
}
neutralButton
.
frame
.
origin
.
x
=
8
neutralButton
.
frame
.
origin
.
x
=
insets
.
left
positiveButton
.
frame
.
origin
.
x
=
width
-
8
-
positiveButton
.
frame
.
width
positiveButton
.
frame
.
origin
.
x
=
width
-
insets
.
right
-
positiveButton
.
frame
.
width
negativeButton
.
frame
.
origin
.
x
=
(
positiveButton
.
isHidden
?
width
:
positiveButton
.
frame
.
minX
)
-
8
-
negativeButton
.
frame
.
width
let
maxX
=
positiveButton
.
isHidden
?
width
-
insets
.
right
:
positiveButton
.
frame
.
minX
-
Constants
.
button
.
interim
negativeButton
.
frame
.
origin
.
x
=
maxX
-
negativeButton
.
frame
.
width
}
}
}
}
...
@@ -173,8 +208,9 @@ private extension DialogView {
...
@@ -173,8 +208,9 @@ private extension DialogView {
let
size
=
CGSize
(
width
:
frame
.
width
,
height
:
contentViewSizeThatFits
(
width
:
frame
.
width
)
.
height
)
let
size
=
CGSize
(
width
:
frame
.
width
,
height
:
contentViewSizeThatFits
(
width
:
frame
.
width
)
.
height
)
contentView
.
frame
.
size
=
size
contentView
.
frame
.
size
=
size
guard
!
detailsLabel
.
isEmpty
else
{
return
}
guard
!
detailsLabel
.
isEmpty
else
{
return
}
let
additional
:
CGFloat
=
titleArea
.
frame
.
height
==
0
?
20
:
0
// if no title area, push 20 points below
let
rect
=
CGRect
(
origin
:
.
zero
,
size
:
size
)
detailsLabel
.
frame
=
CGRect
(
x
:
24
,
y
:
additional
,
width
:
size
.
width
-
24
-
24
,
height
:
size
.
height
-
24
)
let
insets
=
titleArea
.
frame
.
height
==
0
?
Constants
.
contentView
.
insetsNoTitle
:
Constants
.
contentView
.
insets
detailsLabel
.
frame
=
UIEdgeInsetsInsetRect
(
rect
,
insets
)
}
}
func
layoutScrollView
()
{
func
layoutScrollView
()
{
...
@@ -204,7 +240,8 @@ private extension DialogView {
...
@@ -204,7 +240,8 @@ private extension DialogView {
private
extension
Button
{
private
extension
Button
{
var
optimalWidth
:
CGFloat
{
var
optimalWidth
:
CGFloat
{
return
max
(
64
,
sizeThatFits
(
CGSize
(
width
:
.
max
,
height
:
36
))
.
width
)
let
size
=
CGSize
(
width
:
.
greatestFiniteMagnitude
,
height
:
Constants
.
button
.
height
)
return
max
(
Constants
.
button
.
minWidth
,
sizeThatFits
(
size
)
.
width
)
}
}
}
}
...
@@ -223,11 +260,13 @@ private extension DialogView {
...
@@ -223,11 +260,13 @@ private extension DialogView {
let
buttonsWidth
:
CGFloat
=
buttons
.
reduce
(
0
)
{
$0
+
$1
.
optimalWidth
}
let
buttonsWidth
:
CGFloat
=
buttons
.
reduce
(
0
)
{
$0
+
$1
.
optimalWidth
}
let
additional
:
CGFloat
=
neutralButton
.
isHidden
?
0
:
8
// additional spacing for neutral button
let
additional
:
CGFloat
=
neutralButton
.
isHidden
?
0
:
8
// additional spacing for neutral button
return
buttonsWidth
+
CGFloat
(
buttons
.
count
*
8
)
+
additional
let
insets
=
Constants
.
buttonArea
.
insets
return
buttonsWidth
+
insets
.
left
+
insets
.
right
+
CGFloat
((
buttons
.
count
-
1
))
*
Constants
.
button
.
interim
+
additional
}
}
var
requiredButtonAreaWidthForStacked
:
CGFloat
{
var
requiredButtonAreaWidthForStacked
:
CGFloat
{
return
8
+
8
+
nonHiddenButtons
.
reduce
(
0
)
{
let
insets
=
Constants
.
buttonArea
.
insetsStacked
return
insets
.
left
+
insets
.
right
+
nonHiddenButtons
.
reduce
(
0
)
{
max
(
$0
,
$1
.
optimalWidth
)
max
(
$0
,
$1
.
optimalWidth
)
}
}
}
}
...
@@ -266,7 +305,7 @@ private extension DialogView {
...
@@ -266,7 +305,7 @@ private extension DialogView {
[
positiveButton
,
negativeButton
,
neutralButton
]
.
forEach
{
[
positiveButton
,
negativeButton
,
neutralButton
]
.
forEach
{
buttonArea
.
addSubview
(
$0
)
buttonArea
.
addSubview
(
$0
)
$0
.
titleLabel
?
.
font
=
RobotoFont
.
medium
(
with
:
14
)
$0
.
titleLabel
?
.
font
=
RobotoFont
.
medium
(
with
:
14
)
$0
.
contentEdgeInsets
=
UIEdgeInsets
(
top
:
0
,
left
:
8
,
bottom
:
0
,
right
:
8
)
$0
.
contentEdgeInsets
=
Constants
.
button
.
insets
}
}
}
}
...
@@ -291,6 +330,7 @@ private extension UIScrollView {
...
@@ -291,6 +330,7 @@ private extension UIScrollView {
}
}
var
isAtBottom
:
Bool
{
var
isAtBottom
:
Bool
{
// - 1 is to get rid of precision errors which makes divider appear even when scroll is at bottom
return
contentOffset
.
y
>=
(
contentSize
.
height
-
frame
.
height
-
1
)
return
contentOffset
.
y
>=
(
contentSize
.
height
-
frame
.
height
-
1
)
}
}
}
}
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