I'm attempting to put a (vertical) UIStackView in a UIScrollView, but it doesn't seem to want to scroll. Instead it it squishing all the arrangedSubviews into the bounds of the scroll view. autolayout-wise, I'm doing the following:1. constraining the UIScrollView to its superview (top, height, leading and width)2. add a UIView inside the scrollView label it Content View3. constrain the top, bottom, leading, and trailing of the contentView to the scroll view4. constrain contentView's width to match ScrollView's width5. add a vertical UIStackView inside the ContentView6. constrain its top, bottom, leading and trailing values to the contentViewattached is a screen shot link. I have posted a screen shot here: img.gg slash Py9T81yAt the top of the screen shot is a stackview that lays out as expected (not in a scrollView)At the bottom is the stackview inside the scrollView that does not layout correctlyany/all guidance appreciated. (project/source code available if interested)thanks in advance,Mike
Post
Replies
Boosts
Views
Activity
I am currently able to do the following in swiftUI:1. on a button tap, update a model object property2. update a 'separate' swiftUI view (I call it a cell view) that has an @observedObject reference to the model object What I want to do:while updating the cell view, I want to draw attention to it by pulsing its background colour.so the time line would be:1. tap the button2. update the model object2. update the cellView with the model change3. update the cellView background colour (eg Color(white: 0.5))4. animate the cellView background colour back to its original value (eg Color(white: 0.9))Here is code that performs the basic behaviour without the animation.Any/all help with the animation greatly appreciated.thanks,Mikestruct ContentView: View {
let model = Model.shared
var body: some View {
VStack(alignment: .center, spacing: 30.0) {
Button(action: {
self.model.update()
}) {
Text("Tap Here")
}
Cell(model: model)
}
}
}
struct Cell: View {
@ObservedObject var model: Model
var body: some View {
Text(model.myVar)
.background(Color(white: 0.9))
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
class Model: ObservableObject {
@Published var myVar = "Before"
static var shared: Model {
return Model()
}
func update() {
myVar = "After"
}
}
I'm looking to create a grid of square cells. Each square cell will have a 'large' text label in the center and a 'small' textLabel in the bottom left corner.I feel like the pseudo code would look something like:ZStack {
Text("3", horizontalAlignment: .center, verticalAlignment: .center)
.font(.title)
Text("1,2,4", horizontalAlignment: .leading, verticalAlignment: .bottom)
.font(.caption)
}
.border(Color.black, width: 2.0)There would be several rows and several columns of these cells. Their size would then be derived by the number of rows/columns and the available screen space.I've written some code that approximates what I'm going for, but it is using specific frame dimensions.I would prefer to not need specific width/height numbers.struct ContentView: View {
var body: some View {
ZStack() {
Rectangle()
.fill(Color.clear)
.border(Color.black, width: 2.0)
.frame(width: 100, height: 100)
Text("4")
.font(.title)
Text("x")
.alignmentGuide(HorizontalAlignment.center) { d in
return 45
}
.alignmentGuide(VerticalAlignment.center) { d in
return -30
}
.font(.caption)
}
}
}Grateful for any/all help,Mike
I'm attempting to build an app using SwiftUI, and having getting stuck on a few things that I can't figure out how to implement.The current challenge can be described as follows:1. I am displaying a 9x9 grid2. when a user taps one of the 'cell's I want to present an input view that only requires a portion of the screen. (I'm currently picturing it being non-modal, but feel free to convince me it should be otherwise)3. I want the input view to animate its frame starting from the cell the user taps, and ending being a square in the middle of the screen (either a fixed final size, or a fixed final portion of the smaller screen dimension.. or perhaps an intrinsic size?)Any/all help appreciated.here is some UIViewController-based code that implements what I want to doclass ViewController: UIViewController {
override func loadView() {
let result = UIView()
result.backgroundColor = UIColor.blue
addButton(superView: result, title: "button1", yMultiplier: 0.8)
addButton(superView: result, title: "button2", yMultiplier: 1.4)
view = result
}
func addButton(superView: UIView, title: String, yMultiplier: CGFloat) {
let button = UIButton()
button.setTitle(title, for: .normal)
button.backgroundColor = UIColor.green
button.addTarget(self, action: #selector(buttonTapped(sender:)), for: .touchUpInside)
button.translatesAutoresizingMaskIntoConstraints = false
superView.addSubview(button)
let centerX = NSLayoutConstraint(item: button, attribute: .centerX, relatedBy: .equal, toItem: superView, attribute: .centerX, multiplier: 1.0, constant: 0)
let centerY = NSLayoutConstraint(item: button, attribute: .centerY, relatedBy: .equal, toItem: superView, attribute: .centerY, multiplier: yMultiplier, constant: 0)
superView.addConstraints([centerX, centerY])
}
@objc func buttonTapped(sender: UIButton) {
let tempView = UIView(frame: sender.frame)
tempView.backgroundColor = UIColor.red
tempView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
tempView.translatesAutoresizingMaskIntoConstraints = true
view.addSubview(tempView)
UIView.animate(withDuration: 1.0, animations: {
tempView.frame.size = CGSize(width: 200, height: 200)
tempView.center = self.view.center
}) { (success) in
tempView.removeFromSuperview()
}
}}
When I start with this, everything compiles fine:struct ContentView1: View {
@State var shouldShowRect = false
var body: some View {
GeometryReader { geometry in
ZStack() {
VStack() {
Text("Hello, World!")
Text("Hello, World again?")
}
if self.shouldShowRect {
Rectangle()
}
}
}
}
}However when I add a let declaration inside GeometryReader, I get a compile error in xcodestruct ContentView2: View {
@State var shouldShowRect = false
var body: some View {
GeometryReader { geometry in
let dimension = geometry.size.width
ZStack() {
VStack() {
Text("Hello, World!")
Text("Hello, World again?")
}
if self.shouldShowRect {
Rectangle()
}
}
}
}
}at line 6: Closure containing a declaration cannot be used with function builder 'ViewBuilder'The GeometryReader block now needs to explicitly return a view, so I do this:struct ContentView3: View {
@State var shouldShowRect = false
var body: some View {
GeometryReader { geometry in
let dimension = geometry.size.width
let result0 = ZStack() {
VStack() {
Text("Hello, World!")
Text("Hello, World again?")
}
if self.shouldShowRect {
Rectangle()
}
}
return result0
}
}
}This solves the problem at line6, but creates two new problems at lines 4 and 54: Function declares an opaque return type, but has no return statements in its body from which to infer an underlying type5: Cannot convert return expression of type 'GeometryReader<_>' to return type 'some View'I can silence the line4 problem by assigning GeometryReader to a variable and adding a return statement the end of the var body: closure.replace line 05. with the following let result1 = GeometryReader { geometry inadd the following after line 17. return result1but I'm left with two questions:1. how can I silence the error still showing at line5 "cannot convert return expression..."2. Why was the above change (let result1 = GeometryReader...) needed?I have the impression that these two errors, reported at lines 4 & 5 are actually red herrings, and the real syntax problem is somewhere/something else.any/all help greatly appreciated,Mike
I'm getting this error when attempting to upload an iOS app to iTunes Connect. I've tried using Transporter, and get the same result.I've also tried uploading a new version of an app that uploaded correctly in November and got the same result.Does anyone have any suggestions for possible causes for this error?thanks,
In the 'I don't understand why this is happening' category, I'm attempting to initialize a state variable in a View struct, however the initialized value doesn't appear to be sticking. Can any of you see why?I see the following console output:didSet was calledmodelValue: 0 newValue: 12when I run the code belowalso in the ui the displayed value is 0 when I'd expect it to be 12code:struct ContentView: View {
@State var modelValue: Int? {
didSet {
print("didSet was called")
}
}
init() {
updateValue()
}
func updateValue() {
let newValue = 12
modelValue = newValue
print("modelValue: \(modelValue ?? 0) newValue: \(newValue)")
}
var body: some View {
Text("displayValue: \(modelValue ?? 0)")
}
}
I'm attempting to use a UIView subclass in a SwiftUI View-Based designclass MyView: UIView {
weak var delegate: MyViewDelegate?
...
}
protocol MyViewDelegate: class {
func somethingHappened()
}I was hoping I could just do something like:struct WrapperView: UIViewRepresentable {
func makeUIView(context: Context) -> MyView {
let result = MyView()
result.delegate = self
return result
}
}
extension WrapperView: MyViewDelegate {
func somethingHappened() {
// do delegate stuff
}
}I find myself in a catch-22WrapperView can not implement MyViewDelegate because it's a class protocol.If I change the protocol to not be class-based, the delegate iVar can no longer be weak.If I remove the weak reference from the delegate var, (I believe) I will be creating a retain cycle any time MyView's delegate ivar is class.I certainly get why weak (and reference counting) are class only, but is there some way I can define the delegate protocol to allow the delegate ivar to be weak, but still possibly refer to struct?my plan B is to change WrapperView to something like:struct WrapperView: UIViewRepresentable {
var wrappedViewDelegate: WrappedViewDelegate {
return WrappedViewDelegate(parent: self)
}
func makeUIView(context: Context) -> MyView {
let result = MyView()
result.delegate = wrappedViewDelegate
return result
}
func somethingHappened() {
// do delegate stuff
}
}class WrappedViewDelegate: MyViewDelegate {
weak var parent: WrapperView
init(parent: WrapperView) {
parent = parent
}
func somethingHappened() {
parent.somethingHappened()
}
}Does anyone see an alternative to my planB?thanks!
Behaves fine on devices and simulators with newer versions of iOS(haven't yet found a device still at 13.0 to try it on)There is nothing in the console, just the following error:Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)stackTrace (all Apple code) is shown below.As always, any/all suggestions welcome.thanks.#00x00007fff2c046815 in _LayoutTraits.Dimension.init(min:ideal:max:) ()#10x00007fff2c24a8fd in StackLayout.layoutTraits() ()#20x00007fff2c24a7dc in StackLayout.Storage.layoutTraits() ()#30x00007fff2bfaf2c8 in LayoutTraitsProxy.layoutTraits() ()#40x00007fff2c24cc63 in accumulateSpacing #1 (ofChild:) in StackLayout.Header.init(layoutContext:proxies:majorAxis:minorAxisAlignment:uniformSpacing:childStorage:capacity:) ()#50x00007fff2c24c0a5 in StackLayout.Header.init(layoutContext:proxies:majorAxis:minorAxisAlignment:uniformSpacing:childStorage:capacity:) ()#60x00007fff2c24c9ad in specialized ManagedBufferPointer.init(bufferClass:minimumCapacity:makingHeaderWith:) ()#70x00007fff2c24f11c in specialized closure #2 in HVStack.updateOutput<A>(attributeContext:layoutContext:children:) ()#80x00007fff2c25182a in partial apply for specialized ()#90x00007fff2c369fc7 in specialized static LayoutComputerDelegate.update<A>(_:maybeInPlace:create:) ()#100x00007fff2c377930 in specialized static LayoutComputerDelegate.update<A>(_:maybeInPlace:create:) ()#110x00007fff2c24a34c in specialized HVStack.updateOutput<A>(attributeContext:layoutContext:children:) ()#120x00007fff2c24a3b0 in specialized HVStack.updateOutput<A>(attributeContext:layoutContext:children:) ()#130x00007fff2c26804c in specialized LayoutQuery<>.update(context:) ()#140x00007fff2c0e5b2a in partial apply for protocol witness for static UntypedAttribute._update(_:graph:attribute:) in conformance DynamicLayoutViewChildGeometry ()#150x00007fff2f70e429 in AG::Graph::UpdateStack::update() ()#160x00007fff2f70e6e7 in AG::Graph::update_attribute(unsigned int, bool) ()#170x00007fff2f711ceb in AG::Graph::input_value_ref_slow(unsigned int, unsigned int, AGTypeID, bool*) ()#180x00007fff2bfaf2a9 in LayoutTraitsProxy.layoutTraits() ()#190x00007fff2c24cc63 in accumulateSpacing #1 (ofChild:) in StackLayout.Header.init(layoutContext:proxies:majorAxis:minorAxisAlignment:uniformSpacing:childStorage:capacity:) ()#200x00007fff2c24c0a5 in StackLayout.Header.init(layoutContext:proxies:majorAxis:minorAxisAlignment:uniformSpacing:childStorage:capacity:) ()#210x00007fff2c24c9ad in specialized ManagedBufferPointer.init(bufferClass:minimumCapacity:makingHeaderWith:) ()#220x00007fff2c24f11c in specialized closure #2 in HVStack.updateOutput<A>(attributeContext:layoutContext:children:) ()#230x00007fff2c25182a in partial apply for specialized ()#240x00007fff2c369fc7 in specialized static LayoutComputerDelegate.update<A>(_:maybeInPlace:create:) ()#250x00007fff2c24a34c in specialized HVStack.updateOutput<A>(attributeContext:layoutContext:children:) ()#260x00007fff2c24a220 in specialized HVStack.updateOutput<A>(attributeContext:layoutContext:children:) ()#270x00007fff2c267eac in specialized LayoutQuery<>.update(context:) ()#280x00007fff2c0e5b2a in partial apply for protocol witness for static UntypedAttribute._update(_:graph:attribute:) in conformance DynamicLayoutViewChildGeometry ()#290x00007fff2f70e429 in AG::Graph::UpdateStack::update() ()#300x00007fff2f70e6e7 in AG::Graph::update_attribute(unsigned int, bool) ()#310x00007fff2f711ceb in AG::Graph::input_value_ref_slow(unsigned int, unsigned int, AGTypeID, bool*) ()#320x00007fff2bfaf2a9 in LayoutTraitsProxy.layoutTraits() ()#330x00007fff2c24cc63 in accumulateSpacing #1 (ofChild:) in StackLayout.Header.init(layoutContext:proxies:majorAxis:minorAxisAlignment:uniformSpacing:childStorage:capacity:) ()#340x00007fff2c24c0a5 in StackLayout.Header.init(layoutContext:proxies:majorAxis:minorAxisAlignment:uniformSpacing:childStorage:capacity:) ()#350x00007fff2c24c9ad in specialized ManagedBufferPointer.init(bufferClass:minimumCapacity:makingHeaderWith:) ()#360x00007fff2c24f11c in specialized closure #2 in HVStack.updateOutput<A>(attributeContext:layoutContext:children:) ()#370x00007fff2c25182a in partial apply for specialized ()#380x00007fff2c369fc7 in specialized static LayoutComputerDelegate.update<A>(_:maybeInPlace:create:) ()#390x00007fff2c377930 in specialized static LayoutComputerDelegate.update<A>(_:maybeInPlace:create:) ()#400x00007fff2c24a34c in specialized HVStack.updateOutput<A>(attributeContext:layoutContext:children:) ()#410x00007fff2c24a3b0 in specialized HVStack.updateOutput<A>(attributeContext:layoutContext:children:) ()#420x00007fff2c26804c in specialized LayoutQuery<>.update(context:) ()#430x00007fff2c0e5b2a in partial apply for protocol witness for static UntypedAttribute._update(_:graph:attribute:) in conformance DynamicLayoutViewChildGeometry ()#440x00007fff2f70e429 in AG::Graph::UpdateStack::update() ()#450x00007fff2f70e6e7 in AG::Graph::update_attribute(unsigned int, bool) ()#460x00007fff2f711ceb in AG::Graph::input_value_ref_slow(unsigned int, unsigned int, AGTypeID, bool*) ()#470x00007fff2c4b2f2b in _ZStackLayout.layoutTraits(in:children:) ()#480x00007fff2c26a673 in specialized _LayoutEngine.init(layout:layoutContext:children:) ()#490x00007fff2c4fa650 in specialized _Layout<>.updateOutput<A>(attributeContext:layoutContext:children:) ()#500x00007fff2c4fa594 in specialized _Layout<>.updateOutput<A>(attributeContext:layoutContext:children:) ()#510x00007fff2c2682b4 in specialized LayoutQuery<>.update(context:) ()#520x00007fff2c0e5b2a in partial apply for protocol witness for static UntypedAttribute._update(_:graph:attribute:) in conformance DynamicLayoutViewChildGeometry ()#530x00007fff2f70e429 in AG::Graph::UpdateStack::update() ()#540x00007fff2f70e6e7 in AG::Graph::update_attribute(unsigned int, bool) ()#550x00007fff2f711ceb in AG::Graph::input_value_ref_slow(unsigned int, unsigned int, AGTypeID, bool*) ()#560x00007fff2c4b2f2b in _ZStackLayout.layoutTraits(in:children:) ()#570x00007fff2c26a673 in specialized _LayoutEngine.init(layout:layoutContext:children:) ()#580x00007fff2c4fa650 in specialized _Layout<>.updateOutput<A>(attributeContext:layoutContext:children:) ()#590x00007fff2c4fa594 in specialized _Layout<>.updateOutput<A>(attributeContext:layoutContext:children:) ()#600x00007fff2c2682b4 in specialized LayoutQuery<>.update(context:) ()#610x00007fff2c0e5b2a in partial apply for protocol witness for static UntypedAttribute._update(_:graph:attribute:) in conformance DynamicLayoutViewChildGeometry ()#620x00007fff2f70e429 in AG::Graph::UpdateStack::update() ()#630x00007fff2f70e6e7 in AG::Graph::update_attribute(unsigned int, bool) ()#640x00007fff2f713263 in AG::Subgraph::update(unsigned int) ()#650x00007fff2c0b7110 in ViewGraph.runTransaction(in:) ()#660x00007fff2c0b759d in closure #1 in ViewGraph.updateOutputs(at:) ()#670x00007fff2c0b720b in ViewGraph.updateOutputs(at:) ()#680x00007fff2c40d6ea in closure #1 in closure #1 in ViewRendererHost.render(interval:updateDisplayList:) ()#690x00007fff2c40d46c in closure #1 in ViewRendererHost.render(interval:updateDisplayList:) ()#700x00007fff2c40ad47 in ViewRendererHost.render(interval:updateDisplayList:) ()#710x00007fff2c5a5472 in _UIHostingView.layoutSubviews() ()#720x00007fff2c5a5495 in @objc _UIHostingView.layoutSubviews() ()#730x00007fff47636722 in -[UIView(CALayerDelegate) layoutSublayersOfLayer:] ()#740x00007fff2b030ef9 in -[CALayer layoutSublayers] ()#750x00007fff2b0358ff in CA::Layer::layout_if_needed(CA::Transaction*) ()#760x00007fff2b041fe4 in CA::Layer::layout_and_display_if_needed(CA::Transaction*) ()#770x00007fff2af8a4a8 in CA::Context::commit_transaction(CA::Transaction*, double) ()#780x00007fff2afbfab3 in CA::Transaction::commit() ()#790x00007fff4717a1e1 in __34-[UIApplication _firstCommitBlock]_block_invoke_2 ()#800x00007fff23afb8ec in __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ ()#810x00007fff23afb058 in __CFRunLoopDoBlocks ()#820x00007fff23af5ee4 in __CFRunLoopRun ()#830x00007fff23af56b6 in CFRunLoopRunSpecific ()#840x00007fff3815cbb0 in GSEventRunModal ()#850x00007fff47162a67 in UIApplicationMain ()
I'm having a bit of trouble getting my head around publishers.My current project is targetting macOS and iOS. I found a publisher-based way to handle keyboard height changes that works great in iOS.Now I just need to find a way to create an empty/dummy publisher for macOS.(I can solve this problem other ways, but am feeling embarrassed that I can't figure out how to make this empty publisher.)Any/all guidance appreciated.the code snippet below returns the following error at line 16: Unable to infer closure type in the current contextthanks,extension Publishers {
#if os(iOS)
static var keyboardHeight: AnyPublisher<cgfloat, never=""> {
let willShow = NotificationCenter.default.publisher(for: UIApplication.keyboardWillShowNotification)
.map { return $0.keyboardHeight }
let willHide = NotificationCenter.default.publisher(for: UIApplication.keyboardWillHideNotification)
.map { _ in CGFloat(0) }
return MergeMany(willShow, willHide)
.eraseToAnyPublisher()
}
#elseif os(macOS)
static var keyboardHeight = AnyPublisher<cgfloat, never=""> {
return Empty(completeImmediately: false)
}
#endif
}
I can refactor, to avoid having to do this, but what can I use as the var type in the snippet below:var mySwiftUIView: __________?
if shouldUseFancyView() {
mySwiftUIView = FancyView(param: paramValue)
} else {
mySwiftUIView = PlainView(param: otherParamValue)
}
let hostingView = NSHostingView(rootView: mySwiftUIView)In the API, NSHostingView's rootView appears to be of type Content, but it's not clear to me what Content refers to.thanks in advance,Mike
I'm attempting to create a function that will return a swiftUI container. Something like this:
func myStack(content: Text) -> some View {
ZStack{
if self.shouldBeHorizontal() {
HStack(alignment: .center, spacing: 10, content: {content})
} else {
VStack(alignment: .center, spacing: 10, content: {content})
}
}
}
However, I really want toe content input to be more generic.
When I change the function declaration to
func myStack(content: ZStack) -> some View {
The compiler seems to require me to specify the details of the content of the ZStack.
Alternatively, when I try this:
func myStack(content: () -> Content) -> some View {
It complains that Content is an undeclared type.
any/all help greatly appreciated.
thanks,
Mike
I have a row view that shows the details of a podcast object.
It includes a Subscribe/Unsubscribe button (displayed text depends on whether the user is currently subscribed.)
(podcast uses a computed property to express isSubscribed)
This means when a user taps the button, the Subscribe/Unsubscribe text should change, but it does not.
I'm pretty sure I need to use combine for the podcast model object to publish an event, but I don't yet know what this code looks like.
Any chance somebody could let me know how I need to extend the code below to do this?
thanks,
Mike
class SubscriptionsManager {
var subscriptions: [Podcast] = []
static let shared = SubscriptionsManager()
func toggleSubscription(podcast: Podcast) {
}
func isSubscribed(podcast: Podcast) -> Bool {
let result = subscriptions.first{ $0.id == podcast.id }
return result != nil
}
}
class Podcast: Codable {
let title: String
let id: String
var isSubscribed: Bool {
return SubscriptionsManager.shared.isSubscribed(podcast: self)
}
func toggleSubscription() {
SubscriptionsManager.shared.toggleSubscription(podcast: self)
}
}
struct PodcastRowView: View {
@State var podcast: Podcast
var buttonText: String {
return podcast.isSubscribed ? "Unsubscribe" : "Subscribe"
}
var body: some View {
HStack {
Text(podcast.title)
Button(action: {
self.podcast.toggleSubscription()
}) {
Text(self.buttonText)
}
}
}
}
I have a button in my swiftUI view that allows users to open a datePicker and then use the selected date to start a network fetch.
The date picker is presented using this code:
.sheet(isPresented: $showDatePicker) {
ModalDatePicker(startDate: self.podcast.earliestDate,
endDate: self.podcast.latestDate,
currentDate: self.$datePickerDate,
isShowing: self.$showDatePicker,
doneTapped: self.$dateSelected)
}
My plan is to use dateSelected to know when the user taps Done rather than cancelling.
But I'm not sure where I need to check dateSelected.
My first thought was in the body method.
if dateSelected {
dateSelected = false
startFetch()
}
But that doesn't seem to compile, and frankly feels wrong.
I also thought of doing this in ModalDatePicker, but that also feels wrong.
I'm guessing the solution will involve combine and perhaps a publisher, but I don't yet understand how to implement this.
Any assistance would be appreciated.
Thanks,
Mike
I have a swiftUI listView. Each row includes details about a model object, and a button to perform a specific action in the row.
struct EpisodeRowView: View {
@ObservedObject var episode: Episode
var body: some View {
HStack {
if shouldShowRightButton() {
Button(action: {
self.handleRightButtonTap()
}) {
rightButtonImage()
}
.padding(.horizontal)
}
NavigationLink(destination: EpisodeDetailView(episode: episode)) {
Text(episode.title)
}
}
}
Unfortunately when I tap the button it performs the push to the navigation destination.
Is there some way I can prevent/disable this unwanted push?
thanks,
Mike