Skip to content

Latest commit

 

History

History
678 lines (446 loc) · 23.9 KB

File metadata and controls

678 lines (446 loc) · 23.9 KB

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.

Fixed

  • Fixed an issue where Label and AttributedLabel were not accessibility elements.

Added

  • The Environment is now automatically propagated through to nested BlueprintViews within a displayed Element hierarchy. This means that if your view-backed Elements themselves contain a BlueprintView (eg to manage their own state), that nested view will now automatically receive the correct Environment across BlueprintView boundaries. If you were previously manually propagating Environment values you may remove this code. If you would like to opt-out of this behavior; you can set view.automaticallyInheritsEnvironmentFromContainingBlueprintViews = false on your BlueprintView.

  • Lifecycle hooks. You can hook into lifecycle events when an element's visibility changes.

    element
      .onAppear {
        // runs when `element` appears
      }
      .onDisappear {
        // runs when `element` disappears
      }

Removed

Changed

Deprecated

Security

Documentation

Misc

Past Releases

0.27.0 - 2021-06-22

Changed

  • The signature of Element.backingViewDescription(bounds: CGRect, subtreeExtent: CGRect?) -> ViewDescription? has changed to backingViewDescription(with context: ViewDescriptionContext) -> ViewDescription? (square#231). This is a large breaking change, but is worth it as it allows us to pass additional context to backingViewDescription in the future in a non-breaking way. The ViewDescriptionContext contains the bounds and subtreeExtent, as well as the Environment the element is rendered in.

0.26.0 - 2021-06-02

Added

  • Add ScrollTrigger, which adds the ability set the content offset of a ScrollView
  • Add UIViewElementContext to UIViewElement.updateUIView. The context currently has one property, isMeasuring, which tells you if the view being updated is the static measuring instance.

0.25.0 - 2021-05-5

Changed

0.24.0 - 2021-04-16

Added

  • Add Keyed element, which can be used to help differentiate elements during the diff and update process, eg to assist with proper animation transitions.

  • Introduce GridRow, a Row alternative suited for columnar layout. GridRow supports the following:

    • spacing
    • vertical alignment
    • children with absolutely-sized widths
    • children with proportionally-sized widths¹

    ¹Proportional width in this case always means "a proportion of available layout space after spacing and absolutely-sized children are laid out."

    Example:

    GridRow { row in
      row.spacing = 8
      row.verticalAlignment = .center
      row.add(width: .absolute(50), child: authorLabel)
      row.add(width: .proportional(0.75), child: bodyLabel)
      row.add(width: .proportional(0.25), child: dateLabel)
    }
  • Added support to LayoutWriter to allow specifying keys for child Elements.

  • Blueprint can now emit signpost logs during its render pass, which you can use for performance tuning. (#209)

    Signpost logs are disabled by default. To enable them, set BlueprintLogging.enabled = true.

Changed

  • The layout system now uses a caching system to improve performance by eliminating redundant measurements. (#209)

0.23.0 - 2021-03-26

Added

searchField
    .userInteractionEnabled(canBeginSearch)

Changed

0.22.0 - 2021-03-15

Added

  • Introduce Decorate to allow placing a decoration element in front or behind of an Element, without affecting its layout. This is useful for rendering tap or selection states which should overflow the natural bounds of the Element, similar to a shadow, or useful for adding a badge to an Element.

0.21.0 - 2021-02-17

Added

Changed

0.20.0 - 2021-01-12

Added

0.19.1 - 2021-01-06

Removed

0.19.0 - 2021-01-05

Fixed

  • Ensure that Elements are a value type. This is generally assumed by Blueprint, but was previously not validated. This is only validated in DEBUG builds, to avoid otherwise affecting performance.

Added

  • Add LayoutWriter, which makes creating custom / arbitrary layouts much simpler. You no longer need to define a custom Layout type; instead, you can just utilize LayoutWriter and configure and place your children within its builder initializer.

0.18.0 - 2020-12-08

Added

  • Add AccessibilityContainer.identifier ([#180])

0.17.1 - 2020-10-30

Fixed

  • Fixed an issue where view descriptions were applied with unintentional animations while creating backing views. This could happen if an element was added during a transition. (#175)

  • Fixed pull-to-refresh inset for iOS 13+. (#176)

0.17.0 - 2020-10-21

Added

  • Add alignment guides to stacks. (#153)

    Alignment guides let you fine-tune the cross axis alignment. You can specifying a guide value for any child in that element's coordinate space. Children are aligned relatively to each other so that the guide values line up, and then the content as a whole is aligned to the stack's bounds.

    In this example, the center of one element is aligned 10 points from the bottom of another element, and the contents are collectively aligned to the bottom of the row:

    Row { row in
        row.verticalAlignment = .bottom
    
        row.add(
            alignmentGuide: { d in d[VerticalAlignment.center] },
            child: element1
        )
    
        row.add(
            alignmentGuide: { d in d.height - 10 },
            child: element2
        )
    }

Removed

Deprecated

  • Row alignments leading and trailing are deprecated. Use top and bottom instead. (#153)

0.16.0 - 2020-09-22

Fixed

  • Fixed EqualStack to properly constrain children when measuring. (#157)

Added

  • Add a new TransitionContainer.init that supports further customization during initialization and has the same defaults as ViewDescription. (#155, #158)

  • Add transition(onAppear:onDisappear:onLayout) and transition(_:) methods to Element to describe transition animations. (#155, #158)

Removed

  • Remove GridLayout; it's incomplete and was never really intended to be consumed widely. The intended replacement is putting EqualStacks inside of a Column, or Rows inside a Column.

Deprecated

  • TransitionContainer(wrapping:) is deprecated. Use the new TransitionContainer(transitioning:) instead. (#158)

Misc

  • Removed some redundant work being done during rendering. (#154)

0.15.1 - 2020-09-16

Fixed

  • Fixes a crash that can occur in Box when specifying a corner radius and shadow. (#149)

0.15.0 - 2020-09-14

Added

  • Add addFixed(child:) and addFlexible(child:) methods to StackElement for adding children with a grow & shrink priority of 0.0 and 1.0 respectively. (#143)

  • Add capsule case to Box.CornerStyle (#145). This addition sugars the following pattern:

    GeometryReader { geometry in
      Box(cornerStyle: .rounded(geometry.constraint.height.maximum / 2.0))
    }

    into

    Box(cornerStyle: .capsule)
  • Add accessibilityFrameSize to AccessibilityElement for manually specifying a size for the frame rendered by Voice Over. (#144)

  • Add Opacity element for modifying the opacity of a wrapped element. (#147)

Changed

  • BlueprintView will call layoutIfNeeded on backing views during its layout pass. This allows backing views' subviews that are laid out during layoutSubviews to participate in animations. (#139)

0.14.0 - 2020-08-12

Added

  • Add textColor property on TextField (#133).

  • Add the windowSize environment key. (#134)

  • Add GeometryReader. (#135)

    This element allow you to compose elements whose contents depend on the amount of space available.

    Here is an example that dynamically chooses an image based on the width available:

    GeometryReader { (geometry) -> Element in
        let image: UIImage
        switch geometry.constraint.width.maximum {
        case ..<100:
            image = UIImage(named: "small")!
        case 100..<500:
            image = UIImage(named: "medium")!
        default:
            image = UIImage(named: "large")!
        }
        return Image(image: image)
    }

Changed

  • Default ScrollView.delaysContentTouches to true (#132)

Misc

  • Set an explicit shadow path on Box (#137)

0.13.1 - 2020-07-30

Added

  • Introduce AccessibilityContainer element for wrapping an element with multiple sub-elements that should be in a voice over container.

  • Add font property on TextField (#127).

0.13.0 - 2020-07-20

Fixed

  • Update the scroll indicator inset when adjusting the content inset.

  • Label & AttributedLabel use an internal UILabel for measurement. This fixes measurement when there is a line limit set. However, it also means that the screen scale cannot be specified and is always assumed to be UIScreen.main.scale. These elements may not be measured correctly if they are placed on a screen other than UIScreen.main. (#120)

Added

  • Introduce MeasurementCachingKey, to allow for elements to provide a way to cache their measurement during layout passes. This provides performance optimizations for elements whose layout and measurement is expensive to calculate.

  • Introduce UIViewElement to make wrapping self-sizing UIViews easier.

    You can now write a UIViewElement like this:

    struct Switch : UIViewElement
    {
      var isOn : Bool
    
      typealias UIViewType = UISwitch
    
      static func makeUIView() -> UISwitch {
          UISwitch()
      }
    
      func updateUIView(_ view: UISwitch) {
          view.isOn = self.isOn
      }
    }
    

    And the elements will be sized and presented correctly based on the view's sizeThatFits.

  • Add isAccessibilityElement to Label and AttributedLabel. (#120)

  • Add lineHeight to Label for specifying custom line heights. AttributedLabel has a textRectOffset property to support this. (#120)

Changed

0.12.2 - 2020-06-08

Fixed

Added

0.12.1 - 2020-06-05

Fixed

0.12.0 - 2020-06-04

Fixed

  • Removed layout rounding no longer needed since #64 (#95).

Added

  • Add support for the iPhone SE 2 in ElementPreview.

  • Added tintColor and contentMode into the initializer for Image. (#100)

  • Added an Empty element, to mirror EmptyView in SwiftUI. It is an element with no size and draws no content.

  • Environment (#101).

    You can now read and write values from an Environment that is automatically propagated down the element tree. You can use these values to dynamically build the contents of an element, without having to explicitly pass every value through the tree yourself.

    You can read these values with EnvironmentReader:

    struct Foo: ProxyElement {
        var elementRepresentation: Element {
            EnvironmentReader { environment -> Element in
                Label(text: "value from environment: \(environment.foo)")
            }
        }
    }

    And set them with AdaptedEnvironment:

    struct Bar: ProxyElement {
        var elementRepresentation: Element {
            ComplicatedElement()
                .adaptedEnvironment { environment in
                    environment.foo = "bar"
                }
        }
    }

    Several enviroment keys are available by default (#102):

    • calendar
    • display scale
    • layout direction
    • locale
    • safe area insets
    • time zone

    You can create your own by making a type that conforms to EnvironmentKey, and extending Environment with a new property:

    extension Environment {
        private enum FooKey: EnvironmentKey {
            static let defaultValue: String = "default value"
        }
    
        /// The current Foo that elements should use.
        public var foo: String {
            get { self[FooKey.self] }
            set { self[FooKey.self] = newValue }
        }
    }

0.11.0 - 2020-05-10

Fixed

  • Fixed ConstrainedSize to ensure that the measurement of its inner element respects the ConstrainedSize's maximum size, which matters for measuring elements which re-flow based on width, such as elements containing text.

  • Changed BlueprintView.sizeThatFits(:) to treat width and height separately when determining if measurement should be unconstrained in a given axis.

Added

  • Added support for SwiftUI-style element building within BlueprintUI and BlueprintUICommonControls.

    This allows you to replace this code:

    ScrollView(.fittingHeight) (
      wrapping: Box(
        backgroundColor .lightGrey,
        wrapping: Inset(
          uniformInset: 10.0,
          wrapping: ConstrainedSize(
            height: .atLeast(20.0),
            wrapping: Label(
              text: "Hello, world!"
            )
          )
        )
      )
    )

    With this code:

    Label(text: "Hello, World!")
      .constrainedTo(height: .atLeast(20.0))
      .inset(by: 20.0)
      .box(background: .lightGrey)
      .scrollable(.fittingHeight)

    Improving readability and conciseness of your elements.

0.10.0 - 2020-04-27

Added

  • BlueprintView will align view frames to pixel boundaries after layout (#64).

0.9.2 - 2020-04-27

Fixed

  • Don't try to build SwiftUI previews on 32 bit ARM devices – SwiftUI does not exist on these devices.

0.9.1 - 2020-04-17

Fixed

  • Weak link SwiftUI so if an app is not already linking SwiftUI, it will build correctly.

0.9.0 - 2020-04-17

Added

0.8.0 - 2020-04-03

Fixed

  • Properly measure the child of ScrollView to allow for unconstrained measurement.
  • Fix stack layout during underflow (#72)

Added

  • ScrollView can automatically adjust its content inset for the keyboard (#55)

Changed

  • Improved element diffing (#56)

0.7.0 - 2020-03-30

Added

  • Xcode 11 and Swift 5.1 support (#67).

Changed

Removed

  • Raise minimum deployment target from iOS 9.3 to iOS 10 (#66).

0.6.0 - 2020-02-24

Added

  • Add keyboardDismissMode property on ScrollView (#57).
  • Add textAlignment property on TextField (#53).

0.5.0 - 2020-01-24

Fixed

  • Prevent divide-by-zero when a stack contains zero-size elements (#52).

Added

  • Add fill alignment to Aligned (#42).

Documentation

  • Fix typos in the tutorial (#46).
  • Add docs to Overlay (#45).

0.4.0 - 2019-12-04

Fixed

  • Public init on Aligned (#41).

Changed

  • Guarantee that subviews are ordered the same as their associated elements (#32).

0.3.1 - 2019-11-15

Fixed

  • Do not run snapshot tests from CocoaPods (#40).
  • Make tests with float comparisons more lenient for 32-bit (#35).

Added

  • Add Swift Package Manager support (#37).

Documentation

  • Add Getting Started section to README (#38).

0.3.0 - 2019-11-12

Added

  • Add Stack alignment options justifyToStart, justifyToCenter, and justifyToEnd (#24).
  • Add ConstrainedAspectRatio element (#23).
  • Add EqualStack element (#26).
  • Add Rule element (#22).
  • Add Aligned element (#21).
  • Add a screen scale property to some elements (#18).
  • Swift 5 support (#15).

Changed

  • Reorder the parameters of ConstrainedSize, Inset, Button, and Tappapble, so that the wrapped element is the last parameter (#19).

0.2.2 - 2019-03-29

  • First stable release.