我有一个应用程序,我想要显示页面A,用户可以从中导航到页面B或C,从B返回到A或C,从C返回到A,即使用户通过B到达C
目前,当我执行B-> C转换时,我首先PopAsync
返回A,然后我PushAsync
转到C,以便'
问题是:是否存在一种文明的方式来设置此导航方案,同时仍然依靠内置的导航来跟踪导航堆栈 - 我不想自己这样做并使用{ {1}}。
请注意(如图中所示)A和C不是整个导航堆栈的终点,有A之前的页面和C之后的页面,因此必须保留堆栈。
答案 0 :(得分:5)
在iOS上,NavigationRenderer
包含虚拟方法OnPopViewAsync
和OnPushAsync
(类似on Android):
protected override Task<bool> OnPopViewAsync(Page page, bool animated)
{
return base.OnPopViewAsync(page, animated);
}
protected override Task<bool> OnPushAsync(Page page, bool animated)
{
return base.OnPushAsync(page, animated);
}
他们使用两个参数调用相应的基本方法,即页面以及是否为过渡设置动画。因此,您可以使用以下方法启用或禁用动画:
请注意,我还没有尝试过这种方法,但是,因为要完成一些工作。但是,禁用所有导航页面上的动画确实可以这样做。
编辑:我花了几个小时才真正为自己的项目实施解决方案。因此,我将分享更多细节。 (我在Xamarin.Forms 1.2.3-pre4上开发和测试。)
除了上面提到的Animated
属性外,我的导航页面重新实现了两个转换函数,并添加了一个可选参数animated
,默认情况下为true
。这样,我们就可以保留所有现有代码,只需在需要的地方添加false
。
此外,在推送/弹出页面后,两种方法都会睡眠很短的时间(10毫秒)。如果没有这种延迟,我们会在连续的电话中遇到麻烦。
public class CustomNavigationPage: NavigationPage
{
public bool Animated { get; private set; }
public CustomNavigationPage(Page page) : base(page)
{
}
// Analysis disable once MethodOverloadWithOptionalParameter
public async Task PushAsync(Page page, bool animated = true)
{
Animated = animated;
await base.PushAsync(page);
await Task.Run(delegate {
Thread.Sleep(10);
});
}
// Analysis disable once MethodOverloadWithOptionalParameter
public async Task<Page> PopAsync(bool animated = true)
{
Animated = animated;
var task = await base.PopAsync();
await Task.Run(delegate {
Thread.Sleep(10);
});
return task;
}
}
我的自定义导航页面的渲染器会覆盖两种转换方法,并将Animated
属性传递给它们的基本方法。 (以这种方式注入旗帜很难看,但我无法找到更好的解决方案。)
public class CustomNavigationRenderer: NavigationRenderer
{
protected override Task<bool> OnPopViewAsync(Page page, bool animated)
{
return base.OnPopViewAsync(page, (Element as CustomNavigationPage).Animated);
}
protected override Task<bool> OnPushAsync(Page page, bool animated)
{
return base.OnPushAsync(page, (Element as CustomNavigationPage).Animated);
}
}
这适用于iOS。但在Android上几乎完全相同。
为了演示连续推送和弹出页面的可能性,我编写了以下应用程序。
App
课只会创建一个包含在DemoPage
中的新CustomNavigationPage
。请注意,此示例必须可公开访问此示例。
public static class App
{
public static CustomNavigationPage NavigationPage;
public static Page GetMainPage()
{
return NavigationPage = new CustomNavigationPage(new DemoPage("Root"));
}
}
演示页面包含许多按钮,可以按不同的顺序推送和弹出页面。您可以为每次调用false
或PushAsync
添加或删除PopAsync
选项。
public class DemoPage: ContentPage
{
public DemoPage(string title)
{
Title = title;
Content = new StackLayout {
Children = {
new Button {
Text = "Push",
Command = new Command(o => App.NavigationPage.PushAsync(new DemoPage("Pushed"))),
},
new Button {
Text = "Pop",
Command = new Command(o => App.NavigationPage.PopAsync()),
},
new Button {
Text = "Push + Pop",
Command = new Command(async o => {
await App.NavigationPage.PushAsync(new DemoPage("Pushed (will pop immediately)"));
await App.NavigationPage.PopAsync();
}),
},
new Button {
Text = "Pop + Push",
Command = new Command(async o => {
await App.NavigationPage.PopAsync(false);
await App.NavigationPage.PushAsync(new DemoPage("Popped and pushed immediately"));
}),
},
new Button {
Text = "Push twice",
Command = new Command(async o => {
await App.NavigationPage.PushAsync(new DemoPage("Pushed (1/2)"), false);
await App.NavigationPage.PushAsync(new DemoPage("Pushed (2/2)"));
}),
},
new Button {
Text = "Pop twice",
Command = new Command(async o => {
await App.NavigationPage.PopAsync(false);
await App.NavigationPage.PopAsync();
}),
},
},
};
}
}
重要提示:我需要花费数小时的调试时间才能发现您需要使用NavigationPage
(或派生词)的实例,而不是ContentPage
&# 39; s Navigation
!否则,立即调用两次或多次弹出或推送会导致奇怪的行为和崩溃。
答案 1 :(得分:2)
@Falko 您现在可以包含布尔参数:
class QuotesSpider(scrapy.Spider):
name = "dialpad"
def start_requests(self):
urls = [
'https://help.dialpad.com/hc/en-us/categories/201278063-User-Support',
'https://www.domo.com/',
'https://www.zenreach.com/',
'https://www.trendkite.com/',
'https://peloton.com/',
'https://ting.com/',
'https://www.cedar.com/',
'https://tophat.com/',
'https://www.bambora.com/en/ca/',
'https://www.hoteltonight.com/'
]
for url in urls:
BASE_URL = url
yield scrapy.Request(url=url, callback=self.parse)
def parse(self, response):
page = response.url.split("/")[2]
filename = 'quotes-thing-{}.csv'.format(page)
BASE_URL = response.url
# with open(filename, 'wb') as f:
# f.write(response.body)
# # with open(filename, 'r') as f:
with open(filename, 'w') as f:
for selector in response.css('body').xpath('.//text()'):
selector = selector.extract()
f.write(selector)
答案 2 :(得分:0)
目前Xamarin Forms导航非常简洁,我怀疑有一种很好的方法可以实现这一目标。除了做和额外的&#34; Pop&#34;必要时。
答案 3 :(得分:0)
这里有一系列片段,我和其他一些细节一起掀起,以改善iOS版的NaviagationPage。 Link to comment and code on xamarin forums.
答案 4 :(得分:0)
如果我这样做,我会做的是将Page C推送到您的NavigationStack,然后将页面B从堆栈中取出。这样,当您从页面C弹出时,您将转到第A页。
Sub FilterNew()
Dim Cel, Rng As Range
Application.ScreenUpdating = False
Application.DisplayAlerts = False
Sheets.Add(After:=Sheets(Sheets.Count)).Name = "New" 'Adds a new Sheet to store unique values
Sheets(1).Rows("1:1").Copy Sheets("New").Rows("1:1") 'Copies the header row to the new sheet
Set Rng = Sheet(1).Range("B2:B" & Sheet(1).Range("B1").End(xlDown).Row)
For Each Cel In Rng
If Cel.Value <> Sheet(2).Cells(Cel.Row, 2).Value Then Cel.EntireRow.Copy Sheets("New").Range("A" & Rows.Count).End(xlUp).Offset(1, 0) ' The only issue I have with this is that this doesn't actually tell you if the value is unique, it just tells you ins not on the same rows of the first and second sheet - Is this alright with you?
Next
Application.ScreenUpdating = True
Application.DisplayAlerts = True
End Sub
或者,即使您从页面C弹出,也可以从堆栈中删除所有类型页面B的实例,然后弹回1.在这种情况下,页面B将保留在堆栈中,直到您要移回从第C页到第A页。